SF patch #474500: Make OS/2 locks work like posix locks, from Michael

Muller.
This commit is contained in:
Tim Peters 2001-10-31 03:50:45 +00:00
parent 7e0f81e631
commit a6ca4f40d0
2 changed files with 63 additions and 31 deletions

View file

@ -297,6 +297,7 @@ The Dragon De Monsyne
Skip Montanaro Skip Montanaro
Sape Mullender Sape Mullender
Sjoerd Mullender Sjoerd Mullender
Michael Muller
Takahiro Nakayama Takahiro Nakayama
Travers Naran Travers Naran
Fredrik Nehr Fredrik Nehr

View file

@ -101,82 +101,113 @@ PyThread__exit_prog(int status)
#endif /* NO_EXIT_PROG */ #endif /* NO_EXIT_PROG */
/* /*
* Lock support. It has too be implemented as semaphores. * Lock support. This is implemented with an event semaphore and critical
* I [Dag] tried to implement it with mutex but I could find a way to * sections to make it behave more like a posix mutex than its OS/2
* tell whether a thread already own the lock or not. # counterparts.
*/ */
typedef struct os2_lock_t {
int is_set;
HEV changed;
} *type_os2_lock;
PyThread_type_lock PyThread_type_lock
PyThread_allocate_lock(void) PyThread_allocate_lock(void)
{ {
HMTX aLock;
APIRET rc; APIRET rc;
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
dprintf(("PyThread_allocate_lock called\n")); dprintf(("PyThread_allocate_lock called\n"));
if (!initialized) if (!initialized)
PyThread_init_thread(); PyThread_init_thread();
DosCreateMutexSem(NULL, /* Sem name */ lock->is_set = 0;
&aLock, /* the semaphore */
0, /* shared ? */
0); /* initial state */
dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); DosCreateEventSem(NULL, &lock->changed, 0, 0);
return (PyThread_type_lock) aLock; dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
PyThread_get_thread_ident(),
lock->changed));
return (PyThread_type_lock) lock;
} }
void void
PyThread_free_lock(PyThread_type_lock aLock) PyThread_free_lock(PyThread_type_lock aLock)
{ {
type_os2_lock lock = (type_os2_lock)aLock;
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
DosCloseMutexSem((HMTX)aLock); DosCloseEventSem(lock->changed);
free(aLock);
} }
/* /*
* Return 1 on success if the lock was acquired * Return 1 on success if the lock was acquired
* *
* and 0 if the lock was not acquired. This means a 0 is returned * and 0 if the lock was not acquired.
* if the lock has already been acquired by this thread!
*/ */
int int
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
{ {
int success = 1; int done = 0;
ULONG rc, count; ULONG count;
PID pid = 0; PID pid = 0;
TID tid = 0; TID tid = 0;
type_os2_lock lock = (type_os2_lock)aLock;
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(), dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),
aLock, waitflag)); aLock, waitflag));
DosQueryMutexSem((HMTX)aLock,&pid,&tid,&count); while (!done) {
if( tid == PyThread_get_thread_ident() ) { /* if we own this lock */ /* if the lock is currently set, we have to wait for the state to change */
success = 0; if (lock->is_set) {
} else { if (!waitflag)
rc = DosRequestMutexSem((HMTX) aLock, return 0;
(waitflag == 1 ? SEM_INDEFINITE_WAIT : 0)); DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
if( rc != 0) {
success = 0; /* We failed */
}
} }
dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", /*
PyThread_get_thread_ident(),aLock, waitflag, success)); * enter a critical section and try to get the semaphore. If
* it is still locked, we will try again.
*/
if (DosEnterCritSec())
return 0;
return success; if (!lock->is_set) {
lock->is_set = 1;
DosResetEventSem(lock->changed, &count);
done = 1;
}
DosExitCritSec();
}
return 1;
} }
void void PyThread_release_lock(PyThread_type_lock aLock)
PyThread_release_lock(PyThread_type_lock aLock)
{ {
type_os2_lock lock = (type_os2_lock)aLock;
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
if ( DosReleaseMutexSem( (HMTX) aLock ) != 0 ) { if (!lock->is_set) {
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
PyThread_get_thread_ident(), aLock, GetLastError())); 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();
} }
/* /*