blob: 556445e583a19693a78e1d21174c22a0f2f09561 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
Guido van Rossum66020991996-06-11 18:32:18 +00002/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00003
Guido van Rossum66020991996-06-11 18:32:18 +00004#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00005#include <string.h>
Jack Jansen76689572002-01-15 20:36:14 +00006#ifdef __APPLE__
7#define destructor xxdestructor
8#endif
Guido van Rossum66020991996-06-11 18:32:18 +00009#include <pthread.h>
Jack Jansen76689572002-01-15 20:36:14 +000010#ifdef __APPLE__
11#undef destructor
12#endif
Guido van Rossum80230992001-10-12 21:49:17 +000013#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000014
15/* The POSIX spec says that implementations supporting the sem_*
16 family of functions must indicate this by defining
17 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000018#ifdef _POSIX_SEMAPHORES
19#include <semaphore.h>
20#include <errno.h>
21#endif
Guido van Rossum66020991996-06-11 18:32:18 +000022
Guido van Rossum1a623111996-08-08 18:53:41 +000023
Guido van Rossumd6353e21997-05-13 17:51:13 +000024/* try to determine what version of the Pthread Standard is installed.
25 * this is important, since all sorts of parameter types changed from
26 * draft to draft and there are several (incompatible) drafts in
27 * common use. these macros are a start, at least.
28 * 12 May 1997 -- david arnold <davida@pobox.com>
29 */
30
31#if defined(__ultrix) && defined(__mips) && defined(_DECTHREADS_)
32/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
33# define PY_PTHREAD_D4
34
35#elif defined(__osf__) && defined (__alpha)
36/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
37# if !defined(_PTHREAD_ENV_ALPHA) || defined(_PTHREAD_USE_D4) || defined(PTHREAD_USE_D4)
38# define PY_PTHREAD_D4
39# else
40# define PY_PTHREAD_STD
41# endif
42
43#elif defined(_AIX)
Guido van Rossum1a623111996-08-08 18:53:41 +000044/* SCHED_BG_NP is defined if using AIX DCE pthreads
45 * but it is unsupported by AIX 4 pthreads. Default
46 * attributes for AIX 4 pthreads equal to NULL. For
47 * AIX DCE pthreads they should be left unchanged.
48 */
Guido van Rossumd6353e21997-05-13 17:51:13 +000049# if !defined(SCHED_BG_NP)
50# define PY_PTHREAD_STD
51# else
52# define PY_PTHREAD_D7
53# endif
54
Guido van Rossum64f91051997-05-22 20:41:59 +000055#elif defined(__DGUX)
56# define PY_PTHREAD_D6
Guido van Rossum46ff1901997-06-02 22:25:45 +000057
Guido van Rossum532246e1998-05-14 21:01:27 +000058#elif defined(__hpux) && defined(_DECTHREADS_)
Guido van Rossum89df70b1998-05-07 13:28:23 +000059# define PY_PTHREAD_D4
60
Guido van Rossum46ff1901997-06-02 22:25:45 +000061#else /* Default case */
62# define PY_PTHREAD_STD
63
Guido van Rossum1a623111996-08-08 18:53:41 +000064#endif
65
Jack Jansenc51395d2001-08-29 15:24:53 +000066#ifdef USE_GUSI
67/* The Macintosh GUSI I/O library sets the stackspace to
68** 20KB, much too low. We up it to 64K.
69*/
70#define THREAD_STACK_SIZE 0x10000
71#endif
72
Guido van Rossumd6353e21997-05-13 17:51:13 +000073
74/* set default attribute object for different versions */
75
76#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D7)
77# define pthread_attr_default pthread_attr_default
78# define pthread_mutexattr_default pthread_mutexattr_default
79# define pthread_condattr_default pthread_condattr_default
Guido van Rossum64f91051997-05-22 20:41:59 +000080#elif defined(PY_PTHREAD_STD) || defined(PY_PTHREAD_D6)
Guido van Rossumd6353e21997-05-13 17:51:13 +000081# define pthread_attr_default ((pthread_attr_t *)NULL)
82# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
83# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000084#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000085
Guido van Rossumd6353e21997-05-13 17:51:13 +000086
Martin v. Löwiscc898662002-03-17 09:53:51 +000087/* Whether or not to use semaphores directly rather than emulating them with
88 * mutexes and condition variables:
89 */
90#ifdef _POSIX_SEMAPHORES
91# define USE_SEMAPHORES
92#else
93# undef USE_SEMAPHORES
94#endif
95
96
Guido van Rossum80230992001-10-12 21:49:17 +000097/* On platforms that don't use standard POSIX threads pthread_sigmask()
98 * isn't present. DEC threads uses sigprocmask() instead as do most
99 * other UNIX International compliant systems that don't have the full
100 * pthread implementation.
101 */
Martin v. Löwis69c0ff32001-10-15 14:34:42 +0000102#ifdef HAVE_PTHREAD_SIGMASK
Guido van Rossum80230992001-10-12 21:49:17 +0000103# define SET_THREAD_SIGMASK pthread_sigmask
104#else
105# define SET_THREAD_SIGMASK sigprocmask
106#endif
107
108
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000109/* A pthread mutex isn't sufficient to model the Python lock type
110 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
111 * following are undefined:
112 * -> a thread tries to lock a mutex it already has locked
113 * -> a thread tries to unlock a mutex locked by a different thread
114 * pthread mutexes are designed for serializing threads over short pieces
115 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000116 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000117 *
118 * The pthread_lock struct implements a Python lock as a "locked?" bit
119 * and a <condition, mutex> pair. In general, if the bit can be acquired
120 * instantly, it is, else the pair is used to block the thread until the
121 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000122 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000123
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000124typedef struct {
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000125 char locked; /* 0=unlocked, 1=locked */
126 /* a <cond, mutex> pair to handle an acquire of a locked lock */
127 pthread_cond_t lock_released;
128 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000129} pthread_lock;
130
Guido van Rossum9e46e561998-10-07 16:39:47 +0000131#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000132
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000133/*
134 * Initialization.
135 */
Guido van Rossum9e46e561998-10-07 16:39:47 +0000136
137#ifdef _HAVE_BSDI
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000138static
139void _noop(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000140{
141}
142
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000143static void
144PyThread__init_thread(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000145{
146 /* DO AN INIT BY STARTING THE THREAD */
147 static int dummy = 0;
148 pthread_t thread1;
149 pthread_create(&thread1, NULL, (void *) _noop, &dummy);
150 pthread_join(thread1, NULL);
151}
152
153#else /* !_HAVE_BSDI */
154
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000155static void
156PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000157{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000158#if defined(_AIX) && defined(__GNUC__)
159 pthread_init();
160#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000161}
162
Guido van Rossum9e46e561998-10-07 16:39:47 +0000163#endif /* !_HAVE_BSDI */
164
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000165/*
166 * Thread support.
167 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000168
169
Guido van Rossum3c288632001-10-16 21:13:49 +0000170long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000171PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000172{
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000173 pthread_t th;
Guido van Rossume944da81994-05-23 12:43:41 +0000174 int success;
Guido van Rossum80230992001-10-12 21:49:17 +0000175 sigset_t oldmask, newmask;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000176#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000177 pthread_attr_t attrs;
178#endif
Guido van Rossum65d5b571998-12-21 19:32:43 +0000179 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000180 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000181 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000182
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000183#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000184 pthread_attr_init(&attrs);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000185#endif
186#ifdef THREAD_STACK_SIZE
Jack Jansenc51395d2001-08-29 15:24:53 +0000187 pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
188#endif
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000189#ifdef PTHREAD_SYSTEM_SCHED_SUPPORTED
190 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
191#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000192
193 /* Mask all signals in the current thread before creating the new
194 * thread. This causes the new thread to start with all signals
195 * blocked.
196 */
197 sigfillset(&newmask);
198 SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask);
199
Guido van Rossumd6353e21997-05-13 17:51:13 +0000200 success = pthread_create(&th,
201#if defined(PY_PTHREAD_D4)
202 pthread_attr_default,
203 (pthread_startroutine_t)func,
204 (pthread_addr_t)arg
Guido van Rossum64f91051997-05-22 20:41:59 +0000205#elif defined(PY_PTHREAD_D6)
206 pthread_attr_default,
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000207 (void* (*)(void *))func,
Guido van Rossum64f91051997-05-22 20:41:59 +0000208 arg
Guido van Rossumd6353e21997-05-13 17:51:13 +0000209#elif defined(PY_PTHREAD_D7)
210 pthread_attr_default,
211 func,
212 arg
213#elif defined(PY_PTHREAD_STD)
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000214#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000215 &attrs,
216#else
Guido van Rossumd6353e21997-05-13 17:51:13 +0000217 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000218#endif
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000219 (void* (*)(void *))func,
Guido van Rossumd6353e21997-05-13 17:51:13 +0000220 (void *)arg
221#endif
222 );
Guido van Rossum80230992001-10-12 21:49:17 +0000223
224 /* Restore signal mask for original thread */
225 SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL);
226
Fred Drake03459a52001-11-09 16:00:41 +0000227#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000228 pthread_attr_destroy(&attrs);
229#endif
Guido van Rossum701f25e1999-03-15 20:27:53 +0000230 if (success == 0) {
Guido van Rossuma74d0e41998-09-04 13:38:32 +0000231#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
Guido van Rossumd6353e21997-05-13 17:51:13 +0000232 pthread_detach(&th);
233#elif defined(PY_PTHREAD_STD)
Guido van Rossumf4806c21997-04-30 19:59:22 +0000234 pthread_detach(th);
Guido van Rossumd6353e21997-05-13 17:51:13 +0000235#endif
236 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000237#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
238 return (long) th;
239#else
240 return (long) *(long *) &th;
241#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000242}
243
Trent Mick635f6fb2000-08-23 21:33:05 +0000244/* XXX This implementation is considered (to quote Tim Peters) "inherently
245 hosed" because:
246 - It does not guanrantee the promise that a non-zero integer is returned.
247 - The cast to long is inherently unsafe.
248 - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
249 latter return statement (for Alpha OSF/1) are any longer necessary.
250*/
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000251long
252PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000253{
Guido van Rossum44ee4791998-08-27 19:21:53 +0000254 volatile pthread_t threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000255 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000256 PyThread_init_thread();
Guido van Rossum2565bff1995-01-09 17:50:47 +0000257 /* Jump through some hoops for Alpha OSF/1 */
258 threadid = pthread_self();
Trent Mick635f6fb2000-08-23 21:33:05 +0000259#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
260 return (long) threadid;
261#else
Guido van Rossum2565bff1995-01-09 17:50:47 +0000262 return (long) *(long *) &threadid;
Trent Mick635f6fb2000-08-23 21:33:05 +0000263#endif
Guido van Rossume944da81994-05-23 12:43:41 +0000264}
265
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000266static void
267do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000268{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000269 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum730806d1998-04-10 22:27:42 +0000270 if (!initialized) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000271 if (no_cleanup)
272 _exit(0);
273 else
274 exit(0);
Guido van Rossum730806d1998-04-10 22:27:42 +0000275 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000276}
277
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000278void
279PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000280{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000281 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000282}
283
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000284void
285PyThread__exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000286{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000287 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000288}
289
290#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000291static void
292do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000293{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000294 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000295 if (!initialized)
296 if (no_cleanup)
297 _exit(status);
298 else
299 exit(status);
300}
301
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000302void
303PyThread_exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000304{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000305 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000306}
307
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000308void
309PyThread__exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000310{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000311 do_PyThread_exit_prog(status, 1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000312}
313#endif /* NO_EXIT_PROG */
314
Martin v. Löwiscc898662002-03-17 09:53:51 +0000315#ifdef USE_SEMAPHORES
316
317/*
318 * Lock support.
319 */
320
321PyThread_type_lock
322PyThread_allocate_lock(void)
323{
324 sem_t *lock;
325 int status, error = 0;
326
327 dprintf(("PyThread_allocate_lock called\n"));
328 if (!initialized)
329 PyThread_init_thread();
330
331 lock = (sem_t *)malloc(sizeof(sem_t));
332
333 if (lock) {
334 status = sem_init(lock,0,1);
335 CHECK_STATUS("sem_init");
336
337 if (error) {
338 free((void *)lock);
339 lock = NULL;
340 }
341 }
342
343 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
344 return (PyThread_type_lock)lock;
345}
346
347void
348PyThread_free_lock(PyThread_type_lock lock)
349{
350 sem_t *thelock = (sem_t *)lock;
351 int status, error = 0;
352
353 dprintf(("PyThread_free_lock(%p) called\n", lock));
354
355 if (!thelock)
356 return;
357
358 status = sem_destroy(thelock);
359 CHECK_STATUS("sem_destroy");
360
361 free((void *)thelock);
362}
363
364/*
365 * As of February 2002, Cygwin thread implementations mistakenly report error
366 * codes in the return value of the sem_ calls (like the pthread_ functions).
367 * Correct implementations return -1 and put the code in errno. This supports
368 * either.
369 */
370static int
371fix_status(int status)
372{
373 return (status == -1) ? errno : status;
374}
375
376int
377PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
378{
379 int success;
380 sem_t *thelock = (sem_t *)lock;
381 int status, error = 0;
382
383 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
384
385 do {
386 if (waitflag)
387 status = fix_status(sem_wait(thelock));
388 else
389 status = fix_status(sem_trywait(thelock));
390 } while (status == EINTR); /* Retry if interrupted by a signal */
391
392 if (waitflag) {
393 CHECK_STATUS("sem_wait");
394 } else if (status != EAGAIN) {
395 CHECK_STATUS("sem_trywait");
396 }
397
398 success = (status == 0) ? 1 : 0;
399
400 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
401 return success;
402}
403
404void
405PyThread_release_lock(PyThread_type_lock lock)
406{
407 sem_t *thelock = (sem_t *)lock;
408 int status, error = 0;
409
410 dprintf(("PyThread_release_lock(%p) called\n", lock));
411
412 status = sem_post(thelock);
413 CHECK_STATUS("sem_post");
414}
415
416#else /* USE_SEMAPHORES */
417
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000418/*
419 * Lock support.
420 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000421PyThread_type_lock
422PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000423{
424 pthread_lock *lock;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000425 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000426
Guido van Rossum65d5b571998-12-21 19:32:43 +0000427 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000428 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000429 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000430
431 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
Guido van Rossum9e46e561998-10-07 16:39:47 +0000432 memset((void *)lock, '\0', sizeof(pthread_lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000433 if (lock) {
434 lock->locked = 0;
435
436 status = pthread_mutex_init(&lock->mut,
437 pthread_mutexattr_default);
438 CHECK_STATUS("pthread_mutex_init");
439
440 status = pthread_cond_init(&lock->lock_released,
441 pthread_condattr_default);
442 CHECK_STATUS("pthread_cond_init");
443
444 if (error) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000445 free((void *)lock);
446 lock = 0;
447 }
448 }
449
Fred Drakea44d3532000-06-30 15:01:00 +0000450 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000451 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000452}
453
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000454void
455PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000456{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000457 pthread_lock *thelock = (pthread_lock *)lock;
458 int status, error = 0;
459
Fred Drakea44d3532000-06-30 15:01:00 +0000460 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000461
462 status = pthread_mutex_destroy( &thelock->mut );
463 CHECK_STATUS("pthread_mutex_destroy");
464
465 status = pthread_cond_destroy( &thelock->lock_released );
466 CHECK_STATUS("pthread_cond_destroy");
467
468 free((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000469}
470
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000471int
472PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000473{
474 int success;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000475 pthread_lock *thelock = (pthread_lock *)lock;
476 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000477
Fred Drakea44d3532000-06-30 15:01:00 +0000478 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000479
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000480 status = pthread_mutex_lock( &thelock->mut );
481 CHECK_STATUS("pthread_mutex_lock[1]");
482 success = thelock->locked == 0;
483 if (success) thelock->locked = 1;
484 status = pthread_mutex_unlock( &thelock->mut );
485 CHECK_STATUS("pthread_mutex_unlock[1]");
486
487 if ( !success && waitflag ) {
488 /* continue trying until we get the lock */
489
490 /* mut must be locked by me -- part of the condition
491 * protocol */
492 status = pthread_mutex_lock( &thelock->mut );
493 CHECK_STATUS("pthread_mutex_lock[2]");
494 while ( thelock->locked ) {
495 status = pthread_cond_wait(&thelock->lock_released,
496 &thelock->mut);
497 CHECK_STATUS("pthread_cond_wait");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000498 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000499 thelock->locked = 1;
500 status = pthread_mutex_unlock( &thelock->mut );
501 CHECK_STATUS("pthread_mutex_unlock[2]");
502 success = 1;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000503 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000504 if (error) success = 0;
Fred Drakea44d3532000-06-30 15:01:00 +0000505 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000506 return success;
507}
508
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000509void
510PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000511{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000512 pthread_lock *thelock = (pthread_lock *)lock;
513 int status, error = 0;
514
Fred Drakea44d3532000-06-30 15:01:00 +0000515 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000516
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000517 status = pthread_mutex_lock( &thelock->mut );
518 CHECK_STATUS("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000519
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000520 thelock->locked = 0;
521
522 status = pthread_mutex_unlock( &thelock->mut );
523 CHECK_STATUS("pthread_mutex_unlock[3]");
524
525 /* wake up someone (anyone, if any) waiting on the lock */
526 status = pthread_cond_signal( &thelock->lock_released );
527 CHECK_STATUS("pthread_cond_signal");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000528}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000529
530#endif /* USE_SEMAPHORES */