Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 02 Dec 98 11:13:42 -0600
From:      "Richard Seaman, Jr." <lists@tar.com>
To:        "Daniel Eischen" <eischen@vigrid.com>, "jb@cimlogic.com.au" <jb@cimlogic.com.au>, "scrappy@hub.org" <scrappy@hub.org>
Cc:        "freebsd-hackers@FreeBSD.ORG" <freebsd-hackers@FreeBSD.ORG>
Subject:   Re: pthread_cancel() function...
Message-ID:  <199812021713.LAA01440@ns.tar.com>

next in thread | raw e-mail | index | archive | help
On Wed, 2 Dec 1998 11:19:44 -0500 (EST), Daniel Eischen wrote:

>> I was under the impression that pthread_cancel was a manditory,
>> not optional, part of both the POSIX and SS2 specifications.  However,
>> I agree it causes problems when used improperly, and it sure seems
>> like implementing it is a royal pain in the you know what.
>
>I have the guts of it implemented, but just haven't wrapped all
>(any) of the system calls defined as cancellation points.  I put
>it on the back burner to do other things first.  If someone wants
>to finish it before I get back to it, let me know and I'll try
>to clean it up and make it available.

It strikes me that the "pain in the you know what" part of this
is the syscall wrapping -- though its more than syscalls involved.
There are also some libc library functions that are manditory
cancellation points too.

If you wrap a syscall to make it a cancellation point, then each
function in libc that calls the wrapped syscall becomes a cancellation
point too.  The problem with this is that while some of those
functions are optional or manditory cancellation points, others
are not.  The spec also says that function calls that are not
manditory or optional cancellation points should never be cancellation
points (so the user can know when he is subject to cancellation).

In libc (not libc_r) most syscalls are implemented with a leading
underscore, and then the syscall is declared as a weak alias, eg.
equivalent to:

#pragma weak write=_write

There are a few syscalls that have been omitted (eg. sigsuspend,
which is a manditory cancellation point).  However, the library
functions are not implemented in this manner, so wrapping them
is tougher.

In libc_r, of course, the syscalls that are going to be wrapped are
declared as _thread_sys_xxxxxx, and the others are declared without
the leading underscore.

The only way that I have been able to figure to make all this work
for cancellation points is as follows (and I hope you have a better
way):

1) Implement all the libc_r wrapped syscalls with an underscore,
making them equivalent to the libc syscalls.  Optionally declare
them as weak aliases to the normal syscall name.  Eg.

int _write (......)
{
.....
	_thread_sys_write (......)
.....
}
#pragma weak write=_write

2) Reimplement at least the libc library calls that need to
be cancellation points with an underscore, and with weak
aliases, so they too can be overwridden to be cancellation points.

3) Wrap cancellation points to override the weak symbols, eg:

ssize_t                                                                
write(int fd, const void *buf, size_t nbytes)                          
{                                                                      
        int     ret;                                                   
        int oldtype;                                                   
                                                                       
        /* This is a cancellation point */                             
        pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); 
                                                                       
        ret = _write(fd, buf, nbytes);                                 
                                                                       
        /* This is a cancellation point */                             
        pthread_setcanceltype (oldtype, NULL);                         
                                                                       
        return (ret);                                                  
}                                                                      
                                                                       
4) Re-implement all the libc/libc_r functions that call syscalls
or any of the library calls to used the underscored versions 
for their internal calls, so that cancellation points are not
introduced where they're not supposed to be.  

I've implemented the wrapped syscalls as described above for my
port of linux threads (ie. as in point 3 above), and for my
playing around with kernel threads.  (I also have an implementation
of the pthreads cancellation code that I've used with the kernel
threads stuff).  But,  I haven't tried looking at libc as a whole
(ie. points 2 and 4). I'd happily send you the code I've implemented,
and you're free to use it in the cancellation stuff you're working on.



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199812021713.LAA01440>