diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h index 79753dd982..5ab2ad5e95 100644 --- a/headers/posix/pthread.h +++ b/headers/posix/pthread.h @@ -154,16 +154,21 @@ extern int pthread_attr_init(pthread_attr_t *attr); extern int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); extern int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); +/* thread functions */ extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); extern int pthread_detach(pthread_t thread); extern int pthread_equal(pthread_t t1, pthread_t t2); extern void pthread_exit(void *value_ptr); -extern int pthread_join(pthread_t thread, void **value_ptr); +extern int pthread_join(pthread_t thread, void **_value); extern pthread_t pthread_self(void); - extern int pthread_kill(pthread_t thread, int sig); +extern int pthread_cancel(pthread_t thread); +extern int pthread_setcancelstate(int state, int *_oldState); +extern int pthread_setcanceltype(int type, int *_oldType); +extern void pthread_testcancel(void); + /* thread specific data functions */ extern int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); extern int pthread_key_delete(pthread_key_t key); diff --git a/src/system/libroot/posix/pthread/Jamfile b/src/system/libroot/posix/pthread/Jamfile index 23d9f97fc7..7a89bd68f2 100644 --- a/src/system/libroot/posix/pthread/Jamfile +++ b/src/system/libroot/posix/pthread/Jamfile @@ -6,6 +6,7 @@ MergeObject posix_pthread.o : pthread.c pthread_atfork.c pthread_attr.c + pthread_cancel.cpp pthread_cleanup.cpp pthread_cond.c pthread_condattr.c diff --git a/src/system/libroot/posix/pthread/pthread.c b/src/system/libroot/posix/pthread/pthread.c index 7494d7c998..498a3bed49 100644 --- a/src/system/libroot/posix/pthread/pthread.c +++ b/src/system/libroot/posix/pthread/pthread.c @@ -87,6 +87,9 @@ pthread_create(pthread_t *_thread, const pthread_attr_t *_attr, thread->entry = startRoutine; thread->entry_argument = arg; + thread->cancel_state = PTHREAD_CANCEL_ENABLE; + thread->cancel_type = PTHREAD_CANCEL_DEFERRED; + thread->cancelled = false; thread->cleanup_handlers = NULL; if (sPthreadSlot == -1) { diff --git a/src/system/libroot/posix/pthread/pthread_cancel.cpp b/src/system/libroot/posix/pthread/pthread_cancel.cpp new file mode 100644 index 0000000000..924109033e --- /dev/null +++ b/src/system/libroot/posix/pthread/pthread_cancel.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include "pthread_private.h" + +#include + + +int +pthread_cancel(pthread_t thread) +{ + // TODO: notify thread of being cancelled. + fprintf(stderr, "pthread_cancel() is not yet implemented!\n"); + return EINVAL; +} + + +int +pthread_setcancelstate(int state, int *_oldState) +{ + if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE) + return EINVAL; + + pthread_thread* thread = __get_pthread(); + if (thread == NULL) + return EINVAL; + + if (_oldState != NULL) + *_oldState = thread->cancel_state; + + thread->cancel_state = state; + return 0; +} + + +int +pthread_setcanceltype(int type, int *_oldType) +{ + if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS) + return EINVAL; + + pthread_thread* thread = __get_pthread(); + if (thread == NULL) + return EINVAL; + + if (_oldType != NULL) + *_oldType = thread->cancel_type; + + thread->cancel_type = type; + return 0; +} + + +void +pthread_testcancel(void) +{ + pthread_thread* thread = __get_pthread(); + if (thread == NULL) + return; + + if (thread->cancelled && thread->cancel_state == PTHREAD_CANCEL_ENABLE) + pthread_exit(NULL); +} + diff --git a/src/system/libroot/posix/pthread/pthread_private.h b/src/system/libroot/posix/pthread/pthread_private.h index 92f25c132f..d57efecdaa 100644 --- a/src/system/libroot/posix/pthread/pthread_private.h +++ b/src/system/libroot/posix/pthread/pthread_private.h @@ -51,6 +51,9 @@ typedef struct _pthread_attr { struct pthread_thread { void *(*entry)(void*); void *entry_argument; + int cancel_state; + int cancel_type; + bool cancelled; struct __pthread_cleanup_handler *cleanup_handlers; // TODO: move pthread keys in here, too };