Bug 3862

Summary: timeout of pthread_cond_timedwait corrupts condition variable
Product: [Retired] Red Hat Linux Reporter: ham
Component: glibcAssignee: Cristian Gafton <gafton>
Status: CLOSED RAWHIDE QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: 6.0CC: bfc
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-01-05 01:40:38 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description ham 1999-07-01 21:00:03 UTC
If a thread blocks on pthread_cond_timedwait, and other
threads block on pthread_cond_wait and the first thread
times out, a pthread_cond_signal will fail to wake any
thread.

Here is a piece of sample code:

/**********************************************************/

#include <stdio.h>
#include <errno.h>
#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

char buf[512];

int timeout = 1;

void *transient_worker (void *arg)
{
   struct timespec tspec;

   pthread_mutex_lock(&mutex);

   while (1) {
      tspec.tv_sec = time(NULL) + timeout;
      tspec.tv_nsec = 0;

      if (pthread_cond_timedwait(&cond, &mutex, &tspec) ==
ETIMEDOUT)
         break;

      printf("transient worker: %s\n", buf);
   }

   pthread_mutex_unlock(&mutex);
}

void *worker (void *arg)
{
   pthread_mutex_lock(&mutex);

   while (1) {
      pthread_cond_wait(&cond, &mutex);

      printf("worker: %s\n", buf);
   }
}

int main(int argc, char *argv[])
{
   pthread_t tid;

   if (argc > 1)
      timeout = atoi(argv[1]);

   pthread_create(&tid, NULL, transient_worker, NULL);
   pthread_create(&tid, NULL, worker, NULL);

   while (1) {

      scanf("%s", buf);

      pthread_cond_signal(&cond);

   }
}

/**********************************************************/

Ignore the synchronization of "buf" - it's not really an
issue for this example.

If you compile this code and run it with no arguments and
then type a string, nothing is printed out because the
transient worker has exited. However, if you run it with an
argument of say, 20, and then type in a string it then works
fine. Then if you wait 20 seconds before typing in anything
else, the transient thread will die and then it will work
correctly with the one remaining thread. If you type
something in before the 20 seconds is up, then the transient
thread becomes the first thread waiting on the condition
variable and when it dies the program fails...

Comment 1 ham 1999-07-06 15:36:59 UTC
I tested the program on an older Red Hat distribution and it worked
correctly.

The libraries that it failed for are:
        libc-2.1.1.so
        libpthread-0.8.so

It worked with the following libraries:
        libc-2.0.7.so
        libpthread-0.7.so

Comment 2 Cristian Gafton 2000-01-05 01:40:59 UTC
The program seems to work correctly for me with glibc 2.1.3 - which will be
available on this week's rawhide.