diff options
Diffstat (limited to 'contrib/tools/python3/Python/thread_nt.h')
| -rw-r--r-- | contrib/tools/python3/Python/thread_nt.h | 105 |
1 files changed, 67 insertions, 38 deletions
diff --git a/contrib/tools/python3/Python/thread_nt.h b/contrib/tools/python3/Python/thread_nt.h index 26f441bd6d3..3a01a7fe327 100644 --- a/contrib/tools/python3/Python/thread_nt.h +++ b/contrib/tools/python3/Python/thread_nt.h @@ -1,4 +1,5 @@ -#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize +#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize +#include "pycore_time.h" // _PyTime_AsMicroseconds() /* This code implemented by [email protected] */ /* Fast NonRecursiveMutex support by Yakov Markovitch, [email protected] */ @@ -76,17 +77,18 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) } } else if (milliseconds != 0) { /* wait at least until the deadline */ - _PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000); - _PyTime_t deadline = _PyTime_Add(_PyTime_GetPerfCounter(), nanoseconds); + PyTime_t timeout = (PyTime_t)milliseconds * (1000 * 1000); + PyTime_t deadline = _PyDeadline_Init(timeout); while (mutex->locked) { - _PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, - _PyTime_ROUND_TIMEOUT); + PyTime_t microseconds = _PyTime_AsMicroseconds(timeout, + _PyTime_ROUND_TIMEOUT); if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) { result = WAIT_FAILED; break; } - nanoseconds = deadline - _PyTime_GetPerfCounter(); - if (nanoseconds <= 0) { + + timeout = _PyDeadline_Get(deadline); + if (timeout <= 0) { break; } } @@ -182,9 +184,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 +196,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 +209,47 @@ 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); } /* * 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 +257,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. @@ -257,6 +291,14 @@ PyThread_exit_thread(void) _endthreadex(0); } +void _Py_NO_RETURN +PyThread_hang_thread(void) +{ + while (1) { + SleepEx(INFINITE, TRUE); + } +} + /* * Lock support. It has to be implemented as semaphores. * I [Dag] tried to implement it with mutex but I could find a way to @@ -408,16 +450,7 @@ PyThread_set_key_value(int key, void *value) void * PyThread_get_key_value(int key) { - /* because TLS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key); - SetLastError(error); - return result; + return TlsGetValue(key); } void @@ -489,14 +522,10 @@ void * PyThread_tss_get(Py_tss_t *key) { assert(key != NULL); - /* because TSS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key->_key); - SetLastError(error); - return result; + int err = GetLastError(); + void *r = TlsGetValue(key->_key); + if (r || !GetLastError()) { + SetLastError(err); + } + return r; } |
