redmine

Fixed hanging up on shutdown

Fixes: https://github.com/xaionaro/clsync/issues/122

Bug descritpion: The privileged helper process cannot die while
pthread_cond_wait().

Note: fixed, but not fully tested (it's hard to repeat the bug).
@@ -41,3 +41,5 @@ extern int parent_isalive(); @@ -41,3 +41,5 @@ extern int parent_isalive();
41 extern int sethandler_sigchld(void (*handler)()); 41 extern int sethandler_sigchld(void (*handler)());
42 extern pid_t waitpid_timed(pid_t child_pid, int *status_p, long sec, long nsec); 42 extern pid_t waitpid_timed(pid_t child_pid, int *status_p, long sec, long nsec);
43 43
  44 +#define exit_on(cond) { debug(30, "exit_on: checking: %s", TOSTR(cond)); if (unlikely(cond)) { debug(1, "Exiting due to: "TOSTR(cond)); exit(0); } }
  45 +
@@ -824,7 +824,10 @@ int privileged_handler(ctx_t *ctx_p) @@ -824,7 +824,10 @@ int privileged_handler(ctx_t *ctx_p)
824 { 824 {
825 # ifdef READWRITE_SIGNALLING 825 # ifdef READWRITE_SIGNALLING
826 char buf[1] = {0}; 826 char buf[1] = {0};
  827 +# else
  828 + struct timespec wait_timeout = {0};
827 # endif 829 # endif
  830 +
828 int setup = 0; 831 int setup = 0;
829 uid_t exec_uid = 65535; 832 uid_t exec_uid = 65535;
830 gid_t exec_gid = 65535; 833 gid_t exec_gid = 65535;
@@ -901,9 +904,29 @@ int privileged_handler(ctx_t *ctx_p) @@ -901,9 +904,29 @@ int privileged_handler(ctx_t *ctx_p)
901 critical_on(!parent_isalive()); 904 critical_on(!parent_isalive());
902 # endif 905 # endif
903 # ifdef READWRITE_SIGNALLING 906 # ifdef READWRITE_SIGNALLING
  907 +# warning READWRITE_SIGNALLING can cause process hanging on clsync shutdown
904 read_inf(priv_read_fd, buf, 1); 908 read_inf(priv_read_fd, buf, 1);
905 # else 909 # else
906 - critical_on (pthread_cond_wait(pthread_cond_privileged_p, pthread_mutex_privileged_p)); 910 + int rc;
  911 + while (1) {
  912 + rc = pthread_cond_timedwait(pthread_cond_privileged_p, pthread_mutex_privileged_p, &wait_timeout);
  913 + if (!rc)
  914 + break;
  915 + if (rc != ETIMEDOUT)
  916 + critical("Got error while pthread_cond_timedwait()");
  917 + debug(10, "pthread_cond_timedwait() timed out");
  918 +
  919 + if (opts->isprocsplitting)
  920 + exit_on(!parent_isalive());
  921 +
  922 + {
  923 + debug(20, "Resetting wait_timeout");
  924 + struct timeval now;
  925 + gettimeofday(&now, NULL);
  926 + wait_timeout.tv_sec = now.tv_sec + SLEEP_SECONDS;
  927 + wait_timeout.tv_nsec = now.tv_usec * 1000;
  928 + }
  929 + }
907 # endif 930 # endif
908 # ifdef HL_LOCKS 931 # ifdef HL_LOCKS
909 if (hl_lock_p->enabled) 932 if (hl_lock_p->enabled)