int pthread_cancel(pthread_t thread) { _rthread_setflag(thread, THREAD_CANCELLED); return (0); }
void _enter_delayed_cancel(pthread_t self) { if (self->flags & THREAD_CANCEL_ENABLE) { self->delayed_cancel = 0; self->cancel_point++; if (IS_CANCELED(self)) pthread_exit(PTHREAD_CANCELED); _rthread_setflag(self, THREAD_CANCEL_DELAY); } }
int pthread_setcanceltype(int type, int *oldtypep) { pthread_t self = pthread_self(); int oldtype; oldtype = self->flags & THREAD_CANCEL_DEFERRED ? PTHREAD_CANCEL_DEFERRED : PTHREAD_CANCEL_ASYNCHRONOUS; if (type == PTHREAD_CANCEL_DEFERRED) { _rthread_setflag(self, THREAD_CANCEL_DEFERRED); pthread_testcancel(); } else if (type == PTHREAD_CANCEL_ASYNCHRONOUS) { _rthread_clearflag(self, THREAD_CANCEL_DEFERRED); } else { return (EINVAL); } if (oldtypep) *oldtypep = oldtype; return (0); }
int pthread_setcancelstate(int state, int *oldstatep) { pthread_t self = pthread_self(); int oldstate; oldstate = self->flags & THREAD_CANCEL_ENABLE ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE; if (state == PTHREAD_CANCEL_ENABLE) { _rthread_setflag(self, THREAD_CANCEL_ENABLE); pthread_testcancel(); } else if (state == PTHREAD_CANCEL_DISABLE) { _rthread_clearflag(self, THREAD_CANCEL_ENABLE); } else { return (EINVAL); } if (oldstatep) *oldstatep = oldstate; return (0); }
void pthread_exit(void *retval) { struct rthread_cleanup_fn *clfn; pid_t tid; struct stack *stack; pthread_t thread = pthread_self(); thread->retval = retval; for (clfn = thread->cleanup_fns; clfn; ) { struct rthread_cleanup_fn *oclfn = clfn; clfn = clfn->next; oclfn->fn(oclfn->arg); free(oclfn); } _rthread_tls_destructors(thread); _spinlock(&_thread_lock); LIST_REMOVE(thread, threads); _spinunlock(&_thread_lock); _sem_post(&thread->donesem); stack = thread->stack; tid = thread->tid; if (thread->flags & THREAD_DETACHED) _rthread_free(thread); else _rthread_setflag(thread, THREAD_DONE); if (tid != _initial_thread.tid) _rthread_add_to_reaper(tid, stack); _rthread_reaper(); threxit(0); for(;;); }