summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/thread_nt.h58
-rw-r--r--Python/thread_pthread.h71
-rw-r--r--Python/thread_pthread_stubs.h9
3 files changed, 116 insertions, 22 deletions
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
index 26f441b..14b9cdd 100644
--- a/Python/thread_nt.h
+++ b/Python/thread_nt.h
@@ -182,9 +182,9 @@ bootstrap(void *call)
return 0;
}
-unsigned long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
+int
+PyThread_start_joinable_thread(void (*func)(void *), void *arg,
+ PyThread_ident_t* ident, PyThread_handle_t* handle) {
HANDLE hThread;
unsigned threadID;
callobj *obj;
@@ -194,7 +194,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
if (!obj)
- return PYTHREAD_INVALID_THREAD_ID;
+ return -1;
obj->func = func;
obj->arg = arg;
PyThreadState *tstate = _PyThreadState_GET();
@@ -207,22 +207,51 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
/* I've seen errno == EAGAIN here, which means "there are
* too many threads".
*/
- int e = errno;
- threadID = (unsigned)-1;
HeapFree(GetProcessHeap(), 0, obj);
+ return -1;
}
- else {
- CloseHandle(hThread);
+ *ident = threadID;
+ // The cast is safe since HANDLE is pointer-sized
+ *handle = (PyThread_handle_t) hThread;
+ return 0;
+}
+
+unsigned long
+PyThread_start_new_thread(void (*func)(void *), void *arg) {
+ PyThread_handle_t handle;
+ PyThread_ident_t ident;
+ if (PyThread_start_joinable_thread(func, arg, &ident, &handle)) {
+ return PYTHREAD_INVALID_THREAD_ID;
}
- return threadID;
+ CloseHandle((HANDLE) handle);
+ // The cast is safe since the ident is really an unsigned int
+ return (unsigned long) ident;
+}
+
+int
+PyThread_join_thread(PyThread_handle_t handle) {
+ HANDLE hThread = (HANDLE) handle;
+ int errored = (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0);
+ CloseHandle(hThread);
+ return errored;
+}
+
+int
+PyThread_detach_thread(PyThread_handle_t handle) {
+ HANDLE hThread = (HANDLE) handle;
+ return (CloseHandle(hThread) == 0);
+}
+
+void
+PyThread_update_thread_after_fork(PyThread_ident_t* ident, PyThread_handle_t* handle) {
}
/*
* Return the thread Id instead of a handle. The Id is said to uniquely identify the
* thread in the system
*/
-unsigned long
-PyThread_get_thread_ident(void)
+PyThread_ident_t
+PyThread_get_thread_ident_ex(void)
{
if (!initialized)
PyThread_init_thread();
@@ -230,6 +259,13 @@ PyThread_get_thread_ident(void)
return GetCurrentThreadId();
}
+unsigned long
+PyThread_get_thread_ident(void)
+{
+ return (unsigned long) PyThread_get_thread_ident_ex();
+}
+
+
#ifdef PY_HAVE_THREAD_NATIVE_ID
/*
* Return the native Thread ID (TID) of the calling thread.
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 76a1f77..a8df544 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -235,8 +235,8 @@ pythread_wrapper(void *arg)
return NULL;
}
-unsigned long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
+static int
+do_start_joinable_thread(void (*func)(void *), void *arg, pthread_t* out_id)
{
pthread_t th;
int status;
@@ -252,7 +252,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
if (pthread_attr_init(&attrs) != 0)
- return PYTHREAD_INVALID_THREAD_ID;
+ return -1;
#endif
#if defined(THREAD_STACK_SIZE)
PyThreadState *tstate = _PyThreadState_GET();
@@ -261,7 +261,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
if (tss != 0) {
if (pthread_attr_setstacksize(&attrs, tss) != 0) {
pthread_attr_destroy(&attrs);
- return PYTHREAD_INVALID_THREAD_ID;
+ return -1;
}
}
#endif
@@ -272,7 +272,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
if (callback == NULL) {
- return PYTHREAD_INVALID_THREAD_ID;
+ return -1;
}
callback->func = func;
@@ -292,11 +292,34 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
if (status != 0) {
PyMem_RawFree(callback);
- return PYTHREAD_INVALID_THREAD_ID;
+ return -1;
}
+ *out_id = th;
+ return 0;
+}
- pthread_detach(th);
+int
+PyThread_start_joinable_thread(void (*func)(void *), void *arg,
+ PyThread_ident_t* ident, PyThread_handle_t* handle) {
+ pthread_t th = (pthread_t) 0;
+ if (do_start_joinable_thread(func, arg, &th)) {
+ return -1;
+ }
+ *ident = (PyThread_ident_t) th;
+ *handle = (PyThread_handle_t) th;
+ assert(th == (pthread_t) *ident);
+ assert(th == (pthread_t) *handle);
+ return 0;
+}
+unsigned long
+PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+ pthread_t th = (pthread_t) 0;
+ if (do_start_joinable_thread(func, arg, &th)) {
+ return PYTHREAD_INVALID_THREAD_ID;
+ }
+ pthread_detach(th);
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
return (unsigned long) th;
#else
@@ -304,20 +327,46 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
#endif
}
+int
+PyThread_join_thread(PyThread_handle_t th) {
+ return pthread_join((pthread_t) th, NULL);
+}
+
+int
+PyThread_detach_thread(PyThread_handle_t th) {
+ return pthread_detach((pthread_t) th);
+}
+
+void
+PyThread_update_thread_after_fork(PyThread_ident_t* ident, PyThread_handle_t* handle) {
+ // The thread id might have been updated in the forked child
+ pthread_t th = pthread_self();
+ *ident = (PyThread_ident_t) th;
+ *handle = (PyThread_handle_t) th;
+ assert(th == (pthread_t) *ident);
+ assert(th == (pthread_t) *handle);
+}
+
/* XXX This implementation is considered (to quote Tim Peters) "inherently
hosed" because:
- It does not guarantee the promise that a non-zero integer is returned.
- The cast to unsigned long is inherently unsafe.
- It is not clear that the 'volatile' (for AIX?) are any longer necessary.
*/
-unsigned long
-PyThread_get_thread_ident(void)
-{
+PyThread_ident_t
+PyThread_get_thread_ident_ex(void) {
volatile pthread_t threadid;
if (!initialized)
PyThread_init_thread();
threadid = pthread_self();
- return (unsigned long) threadid;
+ assert(threadid == (pthread_t) (PyThread_ident_t) threadid);
+ return (PyThread_ident_t) threadid;
+}
+
+unsigned long
+PyThread_get_thread_ident(void)
+{
+ return (unsigned long) PyThread_get_thread_ident_ex();
}
#ifdef PY_HAVE_THREAD_NATIVE_ID
diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h
index 48bad36..4741e59 100644
--- a/Python/thread_pthread_stubs.h
+++ b/Python/thread_pthread_stubs.h
@@ -94,6 +94,15 @@ pthread_detach(pthread_t thread)
return 0;
}
+int
+pthread_join(pthread_t thread, void** value_ptr)
+{
+ if (value_ptr) {
+ *value_ptr = NULL;
+ }
+ return 0;
+}
+
PyAPI_FUNC(pthread_t) pthread_self(void)
{
return 0;