Mercurial > cpython-lru_cache-weakref
view Python/thread_os2.h @ 40053:693ff5d73412 2.4
Port of universal binary support for Mac OSX from python 2.5. This takes away
the need for the out-of-tree universal binary support that was used to build
the 2.4.3 installer.
Missing here relative to that tree are some changes to IDLE, IMHO those patches
aren't appropriate for the 2.4 branch and users are better of using 2.5's IDLE.
| author | Ronald Oussoren <ronaldoussoren@mac.com> |
|---|---|
| date | Sun, 08 Oct 2006 17:41:25 +0000 |
| parents | 78643be3cf40 |
| children |
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 thread_id; thread_id = _beginthread(func, NULL, THREAD_STACK_SIZE, arg); if (thread_id == -1) { dprintf(("_beginthread failed. return %ld\n", errno)); } return thread_id; } 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 }
