Date: Wed, 28 Nov 2001 10:22:50 -0500 From: "Louis-Philippe Gagnon" <louisphilippe@macadamian.com> To: <freebsd-current@freebsd.org> Subject: posible libc_r pthread bug? Message-ID: <203ca01c17820$8af4a520$2964a8c0@macadamian.com>
next in thread | raw e-mail | index | archive | help
I posted this on -hackers, it was suggested I post it to -current as well
I've encountered a problem using pthread_cancel, pthread_join and
pthread_setcanceltype, I'm hoping someone can shed some light.
(in a nutshell : pthread_setcanceltype doesn't seem to work)
(if there's a more appropriate mailing list for this, please let me know)
I recently encountered a situation where, after calling pthread_cancel to
cancel a thread, the call to pthread_join hangs indefinitely. I quickly figured
out that it was because the thread being cancelled was never reaching a
cancellation point (in fact it was an infinite loop with no function calls at all).
Sure enough, adding a pthread_testcancel() in the loop allowed
pthread_join to return. However this solution isn't acceptable for my requirements.
I discovered the pthread_setcanceltype function and its
PTHREAD_CANCEL_ASYNCHRONOUS parameter, which looked like
they would give me exactly what I needed : allow threads to be cancelled
regardless of what they are doing (basically a pthread equivalent to
TerminateThread).
Unfortunately, my tests have been less than conclusive : pthread_setcanceltype
doesn't seem to do anything at all. It tells me it succeeds, subsequent calls
properly report the previous cancellation type as ASYNCHRONOUS.
But pthread_join still hangs, and adding pthread_testcancel calls still
makes it work...
I'm working on a FreeBSD 4.4-release machine; I ran the same test under
FreeBSD 4.3-release and got the same results. However, running it on a
Linux box (Mandrake release, 2.4.x kernel), I get exactly the results I
was expecting (that is, setting the cancellation type to asynchronous allows
the thread to be cancelled at any time)
see the end of this message for my test program
So the questions are
-am I doing something wrong or misinterpreting the man pages?
-if not, is this a known bug?
-if so, is there a workaround (or is it already fixed)?
-if not, can someone investigate? (I once had a look at the libc_r code
and ran away screaming)
If this turns out to be a bug in libc_r, a suggestion for a work-around
(even a hack) would be much appreciated, even if a proper fix is found and
committed to CVS (requiring an upgrade from 4.4-release installations is
something we'd rather avoid).
now for some disclaimers :
I'm aware that asynchronous cancellations (TerminateThread-style) are an
Evil Thing To Do. Unfortunately I have no choice in the matter.
I'm aware that there are some strict limitations on what a thread is "allowed"
to do while its cancellation type is asynchronous. specifically, it should only
call "cancel-safe" functions. Note that in my test program, the thread being
cancelled doesn't call any functions at all after setting its cancellation type, so
this shouldn't be an issue.
now for the code :
#include <stdio.h>
#include <pthread.h>
/* thread entry point */
void * thread_entry (void *arg)
{
int i;
if(0!=pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL))
{
fprintf(stderr,"setcanceltype failed!\n");
}
fprintf(stderr,"thread_entry entering loop\n");
while(1)
{
i++;
/* uncomment this to insert a cancellation point */
/* pthread_testcancel();*/
}
/* if we see this, it would mean the loop has been optimized out... */
fprintf(stderr, "after loop\n");
}
int main(void)
{
pthread_t thread;
pthread_attr_t attr;
void *pthread_param;
pthread_attr_init(&attr);
fprintf(stderr,"creating thread\n");
pthread_create(&thread,&attr,&thread_entry,NULL);
fprintf(stderr,"thread created; hit enter to cancel it...\n");
getchar();
fprintf(stderr,"cancelling...\n");
if(0!=pthread_cancel(thread))
{
fprintf(stderr,"cancel failed!\n");
}
fprintf(stderr,"after cancel, before join...\n");
if(0!=pthread_join(thread,&pthread_param))
{
fprintf(stderr,"join failed!\n");
}
fprintf(stderr,"after join\n");
}
please ask if more details are needed
Thanks in advance,
Louis-Philippe Gagnon
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?203ca01c17820$8af4a520$2964a8c0>
