I have committed the patch because it looks correct and I saw you based it 
on pthread_setcancelstate(). 

However please bear in mind that both pthread_setcancelstate() and 
pthread_setcanceltype() have ZERO effect on thread cancellation as 
pthread_cancel() is stubbed so OSv does not act on cancellation type nor 
state.

>From what I can tell pthread_cancel() is not very widely used (and possibly 
discouraged) and it would be expensive to implement it correctly. Please 
see this article about its complexity in Linux - 
https://lwn.net/Articles/683118/. 

Also, this fragment from this manual - 
http://cs.uccs.edu/~cchow/pub/rtl/doc/html/MAN/pthread_cancel.3.html - is 
telling:

"This function is a standard POSIX threads function and is one of the 
weaker parts of the POSIX threads specification. The idea is that 
pthread_cancel will request termination of the target *thread* and this 
termination will either take place asynchronously or will be ignored 
depending on the cancel state of the target thread. If the target thread is 
in a DISABLED state, cancel will be pended until the thread goes to an 
ENABLED state. If the target thread has ENABLED it will either be in a 
DEFERRED or ASYNCHRONOUS mode. DEFERRED mode will defer the cancel until 
the thread is in a cancel point (one of a set of POSIX specified functions 
that correspond to states where the thread is sleeping). And so on. The 
semantics are complicated. Note that canceling a thread on a different 
processor is not supported in RTLinux.


Cancel has a bizzare effect on a thread. If the thread is accepting the 
cancel, it will execute whatever cancel handlers it has pushed using 
pthread_cleanup_push. However *a canceled thread holding a mutex is not 
forced to cleanup the mutex lock* and, in general, a canceled thread may 
leave a terrible mess behind. *Our recommendation is to avoid the use of 
this function *as if it were designed by a committee of software 
consultants rubbing their hands with glee at the huge consulting fees they 
would get coming in to rescue your project after the use of pthread_cancel has 
totally randomized the operation of your code. If cancel was not a required 
part of POSIX spec, we would not inflict it on our poor abused operating 
system. Forgive us."

Nadav may shed more light in this area,
Waldek

On Monday, December 30, 2019 at 2:34:10 PM UTC-5, Zhiting Zhu wrote:
>
> Signed-off-by: Zhiting Zhu <zhit...@cs.utexas.edu <javascript:>> 
> --- 
>  libc/pthread.cc | 12 ++++++++++-- 
>  1 file changed, 10 insertions(+), 2 deletions(-) 
>
> diff --git a/libc/pthread.cc b/libc/pthread.cc 
> index 92508147..ac72a874 100644 
> --- a/libc/pthread.cc 
> +++ b/libc/pthread.cc 
> @@ -39,6 +39,7 @@ namespace pthread_private { 
>      __thread void* tsd[tsd_nkeys]; 
>      __thread pthread_t current_pthread; 
>      __thread int cancel_state = PTHREAD_CANCEL_ENABLE; 
> +    __thread int cancel_type = PTHREAD_CANCEL_DEFERRED; 
>   
>      // NOTE: currently, the list of keys and destructor for each is 
> global, 
>      // not per shared object or ELF namespace. So if a shared object uses 
> @@ -736,9 +737,16 @@ int pthread_setcancelstate(int state, int *oldstate) 
>      return 0; 
>  } 
>   
> -int pthread_setcanceltype(int state, int *oldstate) 
> +int pthread_setcanceltype(int type, int *oldtype) 
>  { 
> -    WARN_STUBBED(); 
> +    if (type != PTHREAD_CANCEL_ASYNCHRONOUS && 
> +        type != PTHREAD_CANCEL_DEFERRED) { 
> +        return EINVAL; 
> +    } 
> +    if (oldtype) { 
> +        (*oldtype) = cancel_type; 
> +    } 
> +    cancel_type = type; 
>      return 0; 
>  } 
>   
> -- 
> 2.17.1 
>
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/59ec6065-9f73-4e99-811a-3d2c6e72b7a2%40googlegroups.com.

Reply via email to