Mercurial > cpython-lru_cache-weakref
view Python/thread_os2.h @ 36683:da2a1049215d legacy-trunk
Patch 1413181, by Gabriel Becedillas.
PyThreadState_Delete(): if the auto-GIL-state machinery knows about
the thread state, forget it (since the thread state is being deleted,
continuing to remember it can't help, but can hurt if another thread
happens to get created with the same thread id).
I'll backport to 2.4 next.
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Mon, 27 Feb 2006 17:15:31 +0000 |
| parents | e1a7eb832cb5 |
| children | 3ac8509437df 0b2b076e5908 a19c20c5e5c7 |
line wrap: on
line source
/* This code implemented by cvale@netcom.com */ #define INCL_DOSPROCESS #define INCL_DOSSEMAPHORES #include "os2.h" #include "limits.h" #include "process.h" #if defined(PYCC_GCC) #include <sys/builtin.h> #include <sys/fmutex.h> #else long PyThread_get_thread_ident(void); #endif #if !defined(THREAD_STACK_SIZE) #define THREAD_STACK_SIZE 0x10000 #endif /* * Initialization of the C package, should not be needed. */ static void PyThread__init_thread(void) { } /* * Thread support. */ long PyThread_start_new_thread(void (*func)(void *), void *arg) { int aThread; int success = 0; aThread = _beginthread(func, NULL, THREAD_STACK_SIZE, arg); if (aThread == -1) { success = -1; fprintf(stderr, "aThread failed == %d", aThread); dprintf(("_beginthread failed. return %ld\n", errno)); } return success; } long PyThread_get_thread_ident(void) { #if !defined(PYCC_GCC) PPIB pib; PTIB tib; #endif if (!initialized) PyThread_init_thread(); #if defined(PYCC_GCC) return _gettid(); #else DosGetInfoBlocks(&tib, &pib); return tib->tib_ptib2->tib2_ultid; #endif } static void do_PyThread_exit_thread(int no_cleanup) { dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident())); if (!initialized) if (no_cleanup) _exit(0); else exit(0); _endthread(); } void PyThread_exit_thread(void) { do_PyThread_exit_thread(0); } void PyThread__exit_thread(void) { do_PyThread_exit_thread(1); } #ifndef NO_EXIT_PROG static void do_PyThread_exit_prog(int status, int no_cleanup) { dprintf(("PyThread_exit_prog(%d) called\n", status)); if (!initialized) if (no_cleanup) _exit(status); else exit(status); } void PyThread_exit_prog(int status) { do_PyThread_exit_prog(status, 0); } void PyThread__exit_prog(int status) { do_PyThread_exit_prog(status, 1); } #endif /* NO_EXIT_PROG */ /* * Lock support. This is implemented with an event semaphore and critical * sections to make it behave more like a posix mutex than its OS/2 * counterparts. */ typedef struct os2_lock_t { int is_set; HEV changed; } *type_os2_lock; PyThread_type_lock PyThread_allocate_lock(void) { #if defined(PYCC_GCC) _fmutex *sem = malloc(sizeof(_fmutex)); if (!initialized) PyThread_init_thread(); dprintf(("%ld: PyThread_allocate_lock() -> %lx\n", PyThread_get_thread_ident(), (long)sem)); if (_fmutex_create(sem, 0)) { free(sem); sem = NULL; } return (PyThread_type_lock)sem; #else APIRET rc; type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t)); dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); lock->is_set = 0; DosCreateEventSem(NULL, &lock->changed, 0, 0); dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), lock->changed)); return (PyThread_type_lock)lock; #endif } void PyThread_free_lock(PyThread_type_lock aLock) { #if !defined(PYCC_GCC) type_os2_lock lock = (type_os2_lock)aLock; #endif dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); #if defined(PYCC_GCC) if (aLock) { _fmutex_close((_fmutex *)aLock); free((_fmutex *)aLock); } #else DosCloseEventSem(lock->changed); free(aLock); #endif } /* * Return 1 on success if the lock was acquired * * and 0 if the lock was not acquired. */ int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) { #if !defined(PYCC_GCC) int done = 0; ULONG count; PID pid = 0; TID tid = 0; type_os2_lock lock = (type_os2_lock)aLock; #endif dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(), aLock, waitflag)); #if defined(PYCC_GCC) /* always successful if the lock doesn't exist */ if (aLock && _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT)) return 0; #else while (!done) { /* if the lock is currently set, we have to wait for * the state to change */ if (lock->is_set) { if (!waitflag) return 0; DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT); } /* enter a critical section and try to get the semaphore. If * it is still locked, we will try again. */ if (DosEnterCritSec()) return 0; if (!lock->is_set) { lock->is_set = 1; DosResetEventSem(lock->changed, &count); done = 1; } DosExitCritSec(); } #endif return 1; } void PyThread_release_lock(PyThread_type_lock aLock) { #if !defined(PYCC_GCC) type_os2_lock lock = (type_os2_lock)aLock; #endif dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(), aLock)); #if defined(PYCC_GCC) if (aLock) _fmutex_release((_fmutex *)aLock); #else if (!lock->is_set) { dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError())); return; } if (DosEnterCritSec()) { dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError())); return; } lock->is_set = 0; DosPostEventSem(lock->changed); DosExitCritSec(); #endif }
