blob: 6e921287e172f68a2dd2fe13dd2b27dd25b22a56 [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>
Guido van Rossum66020991996-06-11 18:32:18 +000014
Guido van Rossum1a623111996-08-08 18:53:41 +000015
Guido van Rossumd6353e21997-05-13 17:51:13 +000016/* try to determine what version of the Pthread Standard is installed.
17 * this is important, since all sorts of parameter types changed from
18 * draft to draft and there are several (incompatible) drafts in
19 * common use. these macros are a start, at least.
20 * 12 May 1997 -- david arnold <davida@pobox.com>
21 */
22
23#if defined(__ultrix) && defined(__mips) && defined(_DECTHREADS_)
24/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
25# define PY_PTHREAD_D4
26
27#elif defined(__osf__) && defined (__alpha)
28/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
29# if !defined(_PTHREAD_ENV_ALPHA) || defined(_PTHREAD_USE_D4) || defined(PTHREAD_USE_D4)
30# define PY_PTHREAD_D4
31# else
32# define PY_PTHREAD_STD
33# endif
34
35#elif defined(_AIX)
Guido van Rossum1a623111996-08-08 18:53:41 +000036/* SCHED_BG_NP is defined if using AIX DCE pthreads
37 * but it is unsupported by AIX 4 pthreads. Default
38 * attributes for AIX 4 pthreads equal to NULL. For
39 * AIX DCE pthreads they should be left unchanged.
40 */
Guido van Rossumd6353e21997-05-13 17:51:13 +000041# if !defined(SCHED_BG_NP)
42# define PY_PTHREAD_STD
43# else
44# define PY_PTHREAD_D7
45# endif
46
Guido van Rossum64f91051997-05-22 20:41:59 +000047#elif defined(__DGUX)
48# define PY_PTHREAD_D6
Guido van Rossum46ff1901997-06-02 22:25:45 +000049
Guido van Rossum532246e1998-05-14 21:01:27 +000050#elif defined(__hpux) && defined(_DECTHREADS_)
Guido van Rossum89df70b1998-05-07 13:28:23 +000051# define PY_PTHREAD_D4
52
Guido van Rossum46ff1901997-06-02 22:25:45 +000053#else /* Default case */
54# define PY_PTHREAD_STD
55
Guido van Rossum1a623111996-08-08 18:53:41 +000056#endif
57
Jack Jansenc51395d2001-08-29 15:24:53 +000058#ifdef USE_GUSI
59/* The Macintosh GUSI I/O library sets the stackspace to
60** 20KB, much too low. We up it to 64K.
61*/
62#define THREAD_STACK_SIZE 0x10000
63#endif
64
Guido van Rossumd6353e21997-05-13 17:51:13 +000065
66/* set default attribute object for different versions */
67
68#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D7)
69# define pthread_attr_default pthread_attr_default
70# define pthread_mutexattr_default pthread_mutexattr_default
71# define pthread_condattr_default pthread_condattr_default
Guido van Rossum64f91051997-05-22 20:41:59 +000072#elif defined(PY_PTHREAD_STD) || defined(PY_PTHREAD_D6)
Guido van Rossumd6353e21997-05-13 17:51:13 +000073# define pthread_attr_default ((pthread_attr_t *)NULL)
74# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
75# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000076#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000077
Guido van Rossumd6353e21997-05-13 17:51:13 +000078
Guido van Rossum80230992001-10-12 21:49:17 +000079/* On platforms that don't use standard POSIX threads pthread_sigmask()
80 * isn't present. DEC threads uses sigprocmask() instead as do most
81 * other UNIX International compliant systems that don't have the full
82 * pthread implementation.
83 */
Martin v. Löwis69c0ff32001-10-15 14:34:42 +000084#ifdef HAVE_PTHREAD_SIGMASK
Guido van Rossum80230992001-10-12 21:49:17 +000085# define SET_THREAD_SIGMASK pthread_sigmask
86#else
87# define SET_THREAD_SIGMASK sigprocmask
88#endif
89
90
Guido van Rossumb98b1b31994-05-11 08:42:04 +000091/* A pthread mutex isn't sufficient to model the Python lock type
92 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
93 * following are undefined:
94 * -> a thread tries to lock a mutex it already has locked
95 * -> a thread tries to unlock a mutex locked by a different thread
96 * pthread mutexes are designed for serializing threads over short pieces
97 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000098 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +000099 *
100 * The pthread_lock struct implements a Python lock as a "locked?" bit
101 * and a <condition, mutex> pair. In general, if the bit can be acquired
102 * instantly, it is, else the pair is used to block the thread until the
103 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000104 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000105
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000106typedef struct {
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000107 char locked; /* 0=unlocked, 1=locked */
108 /* a <cond, mutex> pair to handle an acquire of a locked lock */
109 pthread_cond_t lock_released;
110 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000111} pthread_lock;
112
Guido van Rossum9e46e561998-10-07 16:39:47 +0000113#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000114
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000115/*
116 * Initialization.
117 */
Guido van Rossum9e46e561998-10-07 16:39:47 +0000118
119#ifdef _HAVE_BSDI
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000120static
121void _noop(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000122{
123}
124
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000125static void
126PyThread__init_thread(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000127{
128 /* DO AN INIT BY STARTING THE THREAD */
129 static int dummy = 0;
130 pthread_t thread1;
131 pthread_create(&thread1, NULL, (void *) _noop, &dummy);
132 pthread_join(thread1, NULL);
133}
134
135#else /* !_HAVE_BSDI */
136
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000137static void
138PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000139{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000140#if defined(_AIX) && defined(__GNUC__)
141 pthread_init();
142#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000143}
144
Guido van Rossum9e46e561998-10-07 16:39:47 +0000145#endif /* !_HAVE_BSDI */
146
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000147/*
148 * Thread support.
149 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000150
151
Guido van Rossum3c288632001-10-16 21:13:49 +0000152long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000153PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000154{
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000155 pthread_t th;
Guido van Rossume944da81994-05-23 12:43:41 +0000156 int success;
Guido van Rossum80230992001-10-12 21:49:17 +0000157 sigset_t oldmask, newmask;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000158#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000159 pthread_attr_t attrs;
160#endif
Guido van Rossum65d5b571998-12-21 19:32:43 +0000161 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000162 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000163 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000164
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000165#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000166 pthread_attr_init(&attrs);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000167#endif
168#ifdef THREAD_STACK_SIZE
Jack Jansenc51395d2001-08-29 15:24:53 +0000169 pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
170#endif
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000171#ifdef PTHREAD_SYSTEM_SCHED_SUPPORTED
172 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
173#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000174
175 /* Mask all signals in the current thread before creating the new
176 * thread. This causes the new thread to start with all signals
177 * blocked.
178 */
179 sigfillset(&newmask);
180 SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask);
181
Guido van Rossumd6353e21997-05-13 17:51:13 +0000182 success = pthread_create(&th,
183#if defined(PY_PTHREAD_D4)
184 pthread_attr_default,
185 (pthread_startroutine_t)func,
186 (pthread_addr_t)arg
Guido van Rossum64f91051997-05-22 20:41:59 +0000187#elif defined(PY_PTHREAD_D6)
188 pthread_attr_default,
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000189 (void* (*)(void *))func,
Guido van Rossum64f91051997-05-22 20:41:59 +0000190 arg
Guido van Rossumd6353e21997-05-13 17:51:13 +0000191#elif defined(PY_PTHREAD_D7)
192 pthread_attr_default,
193 func,
194 arg
195#elif defined(PY_PTHREAD_STD)
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000196#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000197 &attrs,
198#else
Guido van Rossumd6353e21997-05-13 17:51:13 +0000199 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000200#endif
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000201 (void* (*)(void *))func,
Guido van Rossumd6353e21997-05-13 17:51:13 +0000202 (void *)arg
203#endif
204 );
Guido van Rossum80230992001-10-12 21:49:17 +0000205
206 /* Restore signal mask for original thread */
207 SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL);
208
Fred Drake03459a52001-11-09 16:00:41 +0000209#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000210 pthread_attr_destroy(&attrs);
211#endif
Guido van Rossum701f25e1999-03-15 20:27:53 +0000212 if (success == 0) {
Guido van Rossuma74d0e41998-09-04 13:38:32 +0000213#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
Guido van Rossumd6353e21997-05-13 17:51:13 +0000214 pthread_detach(&th);
215#elif defined(PY_PTHREAD_STD)
Guido van Rossumf4806c21997-04-30 19:59:22 +0000216 pthread_detach(th);
Guido van Rossumd6353e21997-05-13 17:51:13 +0000217#endif
218 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000219#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
220 return (long) th;
221#else
222 return (long) *(long *) &th;
223#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000224}
225
Trent Mick635f6fb2000-08-23 21:33:05 +0000226/* XXX This implementation is considered (to quote Tim Peters) "inherently
227 hosed" because:
228 - It does not guanrantee the promise that a non-zero integer is returned.
229 - The cast to long is inherently unsafe.
230 - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
231 latter return statement (for Alpha OSF/1) are any longer necessary.
232*/
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000233long
234PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000235{
Guido van Rossum44ee4791998-08-27 19:21:53 +0000236 volatile pthread_t threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000237 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000238 PyThread_init_thread();
Guido van Rossum2565bff1995-01-09 17:50:47 +0000239 /* Jump through some hoops for Alpha OSF/1 */
240 threadid = pthread_self();
Trent Mick635f6fb2000-08-23 21:33:05 +0000241#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
242 return (long) threadid;
243#else
Guido van Rossum2565bff1995-01-09 17:50:47 +0000244 return (long) *(long *) &threadid;
Trent Mick635f6fb2000-08-23 21:33:05 +0000245#endif
Guido van Rossume944da81994-05-23 12:43:41 +0000246}
247
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000248static void
249do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000250{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000251 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum730806d1998-04-10 22:27:42 +0000252 if (!initialized) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000253 if (no_cleanup)
254 _exit(0);
255 else
256 exit(0);
Guido van Rossum730806d1998-04-10 22:27:42 +0000257 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000258}
259
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000260void
261PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000262{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000263 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000264}
265
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000266void
267PyThread__exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000268{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000269 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000270}
271
272#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000273static void
274do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000275{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000276 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000277 if (!initialized)
278 if (no_cleanup)
279 _exit(status);
280 else
281 exit(status);
282}
283
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000284void
285PyThread_exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000286{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000287 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000288}
289
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000290void
291PyThread__exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000292{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000293 do_PyThread_exit_prog(status, 1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000294}
295#endif /* NO_EXIT_PROG */
296
297/*
298 * Lock support.
299 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000300PyThread_type_lock
301PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000302{
303 pthread_lock *lock;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000304 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000305
Guido van Rossum65d5b571998-12-21 19:32:43 +0000306 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000307 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000308 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000309
310 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
Guido van Rossum9e46e561998-10-07 16:39:47 +0000311 memset((void *)lock, '\0', sizeof(pthread_lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000312 if (lock) {
313 lock->locked = 0;
314
315 status = pthread_mutex_init(&lock->mut,
316 pthread_mutexattr_default);
317 CHECK_STATUS("pthread_mutex_init");
318
319 status = pthread_cond_init(&lock->lock_released,
320 pthread_condattr_default);
321 CHECK_STATUS("pthread_cond_init");
322
323 if (error) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000324 free((void *)lock);
325 lock = 0;
326 }
327 }
328
Fred Drakea44d3532000-06-30 15:01:00 +0000329 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000330 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000331}
332
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000333void
334PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000335{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000336 pthread_lock *thelock = (pthread_lock *)lock;
337 int status, error = 0;
338
Fred Drakea44d3532000-06-30 15:01:00 +0000339 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000340
341 status = pthread_mutex_destroy( &thelock->mut );
342 CHECK_STATUS("pthread_mutex_destroy");
343
344 status = pthread_cond_destroy( &thelock->lock_released );
345 CHECK_STATUS("pthread_cond_destroy");
346
347 free((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000348}
349
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000350int
351PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000352{
353 int success;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000354 pthread_lock *thelock = (pthread_lock *)lock;
355 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000356
Fred Drakea44d3532000-06-30 15:01:00 +0000357 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000358
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000359 status = pthread_mutex_lock( &thelock->mut );
360 CHECK_STATUS("pthread_mutex_lock[1]");
361 success = thelock->locked == 0;
362 if (success) thelock->locked = 1;
363 status = pthread_mutex_unlock( &thelock->mut );
364 CHECK_STATUS("pthread_mutex_unlock[1]");
365
366 if ( !success && waitflag ) {
367 /* continue trying until we get the lock */
368
369 /* mut must be locked by me -- part of the condition
370 * protocol */
371 status = pthread_mutex_lock( &thelock->mut );
372 CHECK_STATUS("pthread_mutex_lock[2]");
373 while ( thelock->locked ) {
374 status = pthread_cond_wait(&thelock->lock_released,
375 &thelock->mut);
376 CHECK_STATUS("pthread_cond_wait");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000377 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000378 thelock->locked = 1;
379 status = pthread_mutex_unlock( &thelock->mut );
380 CHECK_STATUS("pthread_mutex_unlock[2]");
381 success = 1;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000382 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000383 if (error) success = 0;
Fred Drakea44d3532000-06-30 15:01:00 +0000384 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000385 return success;
386}
387
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000388void
389PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000390{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000391 pthread_lock *thelock = (pthread_lock *)lock;
392 int status, error = 0;
393
Fred Drakea44d3532000-06-30 15:01:00 +0000394 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000395
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000396 status = pthread_mutex_lock( &thelock->mut );
397 CHECK_STATUS("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000398
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000399 thelock->locked = 0;
400
401 status = pthread_mutex_unlock( &thelock->mut );
402 CHECK_STATUS("pthread_mutex_unlock[3]");
403
404 /* wake up someone (anyone, if any) waiting on the lock */
405 status = pthread_cond_signal( &thelock->lock_released );
406 CHECK_STATUS("pthread_cond_signal");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000407}