Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc89866

Browse files
committed
Patch #525532: Add support for POSIX semaphores.
1 parent 8e0c82a commit cc89866

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

Python/thread_pthread.h

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#undef destructor
1212
#endif
1313
#include <signal.h>
14+
#ifdef _POSIX_SEMAPHORES
15+
#include <semaphore.h>
16+
#include <errno.h>
17+
#endif
1418

1519

1620
/* try to determine what version of the Pthread Standard is installed.
@@ -76,6 +80,16 @@
7680
#endif
7781

7882

83+
/* Whether or not to use semaphores directly rather than emulating them with
84+
* mutexes and condition variables:
85+
*/
86+
#ifdef _POSIX_SEMAPHORES
87+
# define USE_SEMAPHORES
88+
#else
89+
# undef USE_SEMAPHORES
90+
#endif
91+
92+
7993
/* On platforms that don't use standard POSIX threads pthread_sigmask()
8094
* isn't present. DEC threads uses sigprocmask() instead as do most
8195
* other UNIX International compliant systems that don't have the full
@@ -294,6 +308,109 @@ PyThread__exit_prog(int status)
294308
}
295309
#endif /* NO_EXIT_PROG */
296310

311+
#ifdef USE_SEMAPHORES
312+
313+
/*
314+
* Lock support.
315+
*/
316+
317+
PyThread_type_lock
318+
PyThread_allocate_lock(void)
319+
{
320+
sem_t *lock;
321+
int status, error = 0;
322+
323+
dprintf(("PyThread_allocate_lock called\n"));
324+
if (!initialized)
325+
PyThread_init_thread();
326+
327+
lock = (sem_t *)malloc(sizeof(sem_t));
328+
329+
if (lock) {
330+
status = sem_init(lock,0,1);
331+
CHECK_STATUS("sem_init");
332+
333+
if (error) {
334+
free((void *)lock);
335+
lock = NULL;
336+
}
337+
}
338+
339+
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
340+
return (PyThread_type_lock)lock;
341+
}
342+
343+
void
344+
PyThread_free_lock(PyThread_type_lock lock)
345+
{
346+
sem_t *thelock = (sem_t *)lock;
347+
int status, error = 0;
348+
349+
dprintf(("PyThread_free_lock(%p) called\n", lock));
350+
351+
if (!thelock)
352+
return;
353+
354+
status = sem_destroy(thelock);
355+
CHECK_STATUS("sem_destroy");
356+
357+
free((void *)thelock);
358+
}
359+
360+
/*
361+
* As of February 2002, Cygwin thread implementations mistakenly report error
362+
* codes in the return value of the sem_ calls (like the pthread_ functions).
363+
* Correct implementations return -1 and put the code in errno. This supports
364+
* either.
365+
*/
366+
static int
367+
fix_status(int status)
368+
{
369+
return (status == -1) ? errno : status;
370+
}
371+
372+
int
373+
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
374+
{
375+
int success;
376+
sem_t *thelock = (sem_t *)lock;
377+
int status, error = 0;
378+
379+
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
380+
381+
do {
382+
if (waitflag)
383+
status = fix_status(sem_wait(thelock));
384+
else
385+
status = fix_status(sem_trywait(thelock));
386+
} while (status == EINTR); /* Retry if interrupted by a signal */
387+
388+
if (waitflag) {
389+
CHECK_STATUS("sem_wait");
390+
} else if (status != EAGAIN) {
391+
CHECK_STATUS("sem_trywait");
392+
}
393+
394+
success = (status == 0) ? 1 : 0;
395+
396+
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
397+
return success;
398+
}
399+
400+
void
401+
PyThread_release_lock(PyThread_type_lock lock)
402+
{
403+
sem_t *thelock = (sem_t *)lock;
404+
int status, error = 0;
405+
406+
dprintf(("PyThread_release_lock(%p) called\n", lock));
407+
408+
status = sem_post(thelock);
409+
CHECK_STATUS("sem_post");
410+
}
411+
412+
#else /* USE_SEMAPHORES */
413+
297414
/*
298415
* Lock support.
299416
*/
@@ -405,3 +522,5 @@ PyThread_release_lock(PyThread_type_lock lock)
405522
status = pthread_cond_signal( &thelock->lock_released );
406523
CHECK_STATUS("pthread_cond_signal");
407524
}
525+
526+
#endif /* USE_SEMAPHORES */

0 commit comments

Comments
 (0)