title: Is gettimeofday async signal safe ? and can it cause deadlock if used in signal handler?
body: <p>Previously I had asked a <a href="https://stackoverflow.com/questions/52391701/pthread-kill-vs-pthread-cancel-to-terminate-a-thread-blocked-for-i-o">question</a> regarding how to terminate thread blocked for I/O. I have used <code>pthread_kill()</code> instead of <code>pthread_cancel()</code> or writing to pipes, considering few advantages. After implementing the code to send signal (SIGUSR2) to the target thread using <code>pthread_kill()</code>, initially it worked fine and didn't face any issues. </p>
  
  <pre><code>static void signalHandler(int signum) {
      LogInfo("SIGNAL HANDLER : %d",signum);  //print info message using logger utility
  }
  
  void setSignalHandler() {
      struct sigaction actions;
  
      memset(&amp;actions, 0, sizeof(actions));
      sigemptyset(&amp;actions.sa_mask);
      actions.sa_flags = 0;
      actions.sa_handler = signalHandler;
  
      int rc = sigaction(SIGUSR2,&amp;actions,NULL);
      if(rc &lt; 0) {
          LogError("Error in sigaction");  //print error using logger utility
      }
  }
  
  void stopThread() {
      fStop = 1;  //set the flag to stop the thread
      if( ftid ) { //ftid is pthread_t variable of thread that needs to be terminated.
          LogInfo("Before pthread_kill()");
          int kill_result = pthread_kill(ftid,SIGUSR2);  // send signal to interrupt the thread if blocked for poll() I/O
          LogInfo("pthread_kill() returned : %d ( %s )",kill_result,strerror(kill_result));
          int result = pthread_join( ftid, NULL );
          LogInfo("Event loop stopped for %s", fStreamName);
          LogInfo( "pthread_join() -&gt; %d ( %s )\n", result, strerror(result) );
          if( result == 0 ) ftid = 0;
      }
  }
  </code></pre>
  
  <p>Recently I have noticed a deadlock issue where few threads (which tried to log statements) blocked with below stacktrace</p>
  
  <pre><code>#0  0x00007fc1b2dc565c in __lll_lock_wait_private () from /lib64/libc.so.6
  #1  0x00007fc1b2d70f0c in _L_lock_2462 () from /lib64/libc.so.6
  #2  0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
  #3  0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
  </code></pre>
  
  <p><code>getCurrentTimestamp(char*)</code> function is called from our logger module when <code>LogInfo()</code> or <code>LogError()</code> functions are invoked. This function internally calls gettimeofday() to print the current time in logs. So I'm suspecting <code>LogInfo()</code> function (which calls <code>gettimeofday()</code>) called inside signalHandler() might be causing the deadlock issue. But i'm not confident of this as this issue is not getting reproduced frequently and i did not get any information stating that <code>gettimeofday()</code> is not async signal safe. </p>
  
  <p>gettimeofday() is <a href="https://stackoverflow.com/questions/3220224/is-the-gettimeofday-function-thread-safe-in-linux">thread safe</a> and i'm considering it's not async signal safe as it was not listed under <a href="http://man7.org/linux/man-pages/man7/signal-safety.7.html" rel="nofollow noreferrer">async signal safe functions</a>. </p>
  
  <p>1) Can I consider <code>gettimeofday()</code> is not async signal safe and it was the root cause of deadlock ?</p>
  
  <p>2) Are there any known issues where use of <code>pthread_kill()</code> might cause deadlock ?</p>
  
  <p><strong>EDIT :</strong> </p>
  
  <p>Below is the definition of <code>getCurrentTimeStamp()</code> function </p>
  
  <pre><code>char* Logger::getCurrentTimestamp ( char *tm_buff ) {
      char curr_time[ 32 ] = { 0 };
      time_t current = time( NULL );
      struct timeval detail_time;
  
      if ( tm_buff ) {
          strftime( curr_time, sizeof(curr_time), "%Y-%m-%d-%H:%M:%S", localtime( &amp;current ) );
          gettimeofday( &amp;detail_time, NULL );
          sprintf( tm_buff, "%s:%03d", curr_time, (int) (detail_time.tv_usec / 1000) );
          return (tm_buff);
      }
      return (NULL);
  }
  </code></pre>
  
  <p>stack trace of the thread that was interrupted by signal.</p>
  
  <pre><code>#0  0x00007fc1b2dc565c in __lll_lock_wait_private () from /lib64/libc.so.6
  #1  0x00007fc1b2d70f0c in _L_lock_2462 () from /lib64/libc.so.6
  #2  0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
  #3  0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
  #4  0x000000000046e80f in Log::write(Logger*, LogType, std::string const&amp;, char const*) ()
  #5  0x000000000046df74 in Log::i(Logger*, char const*, std::string const&amp;, std::string const&amp;, char const*, ...) ()
  #6  0x0000000000456b67 in ?? ()
  #7  &lt;signal handler called&gt;
  #8  0x00007fc1b2da8dc5 in _xstat () from /lib64/libc.so.6
  #9  0x00007fc1b2d71056 in __tzfile_read () from /lib64/libc.so.6
  #10 0x00007fc1b2d703b4 in tzset_internal () from /lib64/libc.so.6
  #11 0x00007fc1b2d70d63 in __tz_convert () from /lib64/libc.so.6
  #12 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
  #13 0x000000000047030e in Logger::writeLog(int, std::string&amp;, std::string&amp;) ()
  #14 0x0000000000470633 in Logger::Write(Logger*, int, std::string, std::string const&amp;) ()
  #15 0x000000000046eb02 in Log::write(Logger*, LogType, std::string const&amp;, char const*) ()
  #16 0x000000000046df74 in Log::i(Logger*, char const*, std::string const&amp;, std::string const&amp;, char const*, ...) ()
  </code></pre>