title: sem_wait not unblocking with EINTR
body: <p>I'm new with semaphores and want to add multithreading to my program, but I cannot get around the following problem: sem_wait() should be able to receive a EINTR and unblock, as long as I didn't set the SA_RESTART flag. I am sending a SIGUSR1 to the worker thread that is blocking in sem_wait(), it does receive the signal and get interrupted, but it will then continue to block and so it will never give me a -1 return code together with errno = EINTR. However, if I do a sem_post from the main thread, it will unblock, give me an errno of EINTR but a RC of 0. I am totally puzzled with this behavior. Is it some weird NetBSD implementation or am I doing something wrong here? According to the man page, sem_wait is conform POSIX.1 (ISO/IEC 9945-1:1996). A simple code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;semaphore.h&gt;
  
  typedef struct workQueue_s
  {
     int full;
     int empty;
     sem_t work;
     int sock_c[10];
  } workQueue_t;
  
  void signal_handler( int sig )
  {
     switch( sig )
     {
        case SIGUSR1:
        printf( "Signal: I am pthread %p\n", pthread_self() );
        break;
     }
  }
  
  extern int errno;
  workQueue_t queue;
  pthread_t workerbees[8];
  
  void *BeeWork( void *t )
  {
     int RC;
     pthread_t tid;
     struct sigaction sa;
     sa.sa_handler = signal_handler;
     sigaction( SIGUSR1, &amp;sa, NULL );
  
     printf( "Bee: I am pthread %p\n", pthread_self() );
     RC = sem_wait( &amp;queue.work );
     printf( "Bee: got RC = %d and errno = %d\n", RC, errno );
  
     RC = sem_wait( &amp;queue.work );
     printf( "Bee: got RC = %d and errno = %d\n", RC, errno );
     pthread_exit( ( void * ) t );
  }
  
  int main()
  {
     int RC;
     long tid = 0;
     pthread_attr_t attr;
     pthread_attr_init( &amp;attr );
     pthread_attr_setdetachstate( &amp;attr, PTHREAD_CREATE_JOINABLE );
  
     queue.full = 0;
     queue.empty = 0;
     sem_init( &amp;queue.work, 0, 0 );
  
     printf( "I am pthread %p\n", pthread_self() );
     pthread_create( &amp;workerbees[tid], &amp;attr, BeeWork, ( void * ) tid );
     pthread_attr_destroy( &amp;attr );
  
     sleep( 2 );
     sem_post( &amp;queue.work );
     sleep( 2 );
     pthread_kill( workerbees[tid], SIGUSR1 );
     sleep( 2 );
  
     // Remove this and sem_wait will stay blocked
     sem_post( &amp;queue.work );
     sleep( 2 );
     return( 0 );
  }
  </code></pre>
  
  <p>I know the printf is not aloud in the signal handler, but just for the heck of it, if I remove it I get the same results.</p>
  
  <p>These are the results without sem_post:</p>
  
  <pre><code>I am pthread 0x7f7fffc00000
  Bee: I am pthread 0x7f7ff6c00000
  Bee: got RC = 0 and errno = 0
  Signal: I am pthread 0x7f7ff6c00000
  </code></pre>
  
  <p>And with the sem_post:</p>
  
  <pre><code>I am pthread 0x7f7fffc00000
  Bee: I am pthread 0x7f7ff6c00000
  Bee: got RC = 0 and errno = 0
  Signal: I am pthread 0x7f7ff6c00000
  Bee: got RC = 0 and errno = 4
  </code></pre>
  
  <p>I know I don't really need to unblock and can simply do an exit from main, but I want to see it working anyway. The reason I'm using sem_wait is because I want to keep the worker threads alive and wake the one up waiting the longest from the main thread with sem_post, as soon as there is a new client connection from Postfix. I don't want to do pthread_create all the time, since I will receive calls multiple times per second and I don't want to lose speed and make Postfix unresponsive to new smtpd clients. It is a policydaemon for Postfix and the server is quite busy.</p>
  
  <p>Am I missing something here? Is NetBSD just messed up with this?</p>