From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Kevin D. Clark" To: Pthreads Developers List Subject: pthread_cancel() problems Date: Wed, 02 Feb 2000 10:08:00 -0000 Message-id: <14488.29431.528635.717936@cabletron.com> References: <14453.4956.759854.712859@cabletron.com> <14463.19695.396800.542343@cabletron.com> <14463.20160.891089.94040@cabletron.com> <14463.20741.97491.269465@cabletron.com> X-SW-Source: 2000/msg00014.html Hi, Is anybody else successfully using pthread_cancel() with this library? I can't seem to get it to work, and I haven't been able to track down the cause of the problem yet. I'm not using asynchronous cancelation either. At the end of this mail I will include another test program that shows off this problem. If the program ran correctly then you'd see a stream of increasing numbers on your screen. However, since the cleanup routine (associated with pthread_cleanup_push()) is never called, the counter remains at zero. So I strongly suspect that there's a bug in the library here. I just wish I could find it. --kevin PS The program works as expected on a Solaris 2.6 box. /* Compiling this program as a C or C++ program doesn't seem to have * an effect on the fact that calling pthread_cancel() doesn't cause * the canceledRoutine() to be invoked. * * Environment: VC++ 6.x, NT 4.x, service pack 5 * Pthreads-win32 snapshot 1999-11-02 */ #include #include #ifdef __unix #include #endif #include void *canceledRoutine(void *); static volatile int counter = 0; /* volatile thrown in out of desperation */ pthread_t canceledThread; pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cv = PTHREAD_COND_INITIALIZER; static int okToCancel = 0; int main(int argc, char *argv[]) { int i = 0; pthread_attr_t tattr; pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); for (i=0; i<100; i++) { /* fprintf(stderr, "iteration %d\n", i); */ pthread_create(&canceledThread, &tattr, canceledRoutine, (void *)i); pthread_mutex_lock(&mu); while (! okToCancel) { int result; result = pthread_cond_wait(&cv, &mu); if (result == EINTR) { fprintf(stderr, "%s:%d: interupted!\n", __FILE__, __LINE__); } } pthread_mutex_unlock(&mu); /* at this point we know that the other thread has pushed a cleanup handler onto its stack */ pthread_cancel(canceledThread); okToCancel = 0; fprintf(stderr, "counter is %d\n", counter); } return 0; } void cancelCleanup(void *arg) { int i = (int)arg; counter++; fprintf(stderr, "%d -- Hey, I've been canceled!\n", i); } void * canceledRoutine(void *arg) { int i = (int)arg; int ignored; /* * My understanding is that the default is for deferred * cancelation, but I'll do this anyways here just to be absolutely * sure. */ if (pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &ignored) != 0) { fprintf(stderr, "problem with pthread_setcanceltype()\n"; } pthread_cleanup_push(cancelCleanup, (void *)i); pthread_mutex_lock(&mu); okToCancel = 1; pthread_mutex_unlock(&mu); pthread_cond_signal(&cv); while(1) { #ifdef __unix /* sleep() is defined to be a cancelation point */ sleep(1); #else /* I'm not totally sure what is defined to be a cancelation point. * Perhaps this needs to be documented? */ Sleep(1000); #endif } pthread_cleanup_pop(0); return 0; }