~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Python/thread_pth.h

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* GNU pth threads interface
 
3
   http://www.gnu.org/software/pth
 
4
   2000-05-03 Andy Dustman <andy@dustman.net>
 
5
 
 
6
   Adapted from Posix threads interface 
 
7
   12 May 1997 -- david arnold <davida@pobox.com>
 
8
 */
 
9
 
 
10
#include <stdlib.h>
 
11
#include <string.h>
 
12
#include <pth.h>
 
13
 
 
14
/* A pth mutex isn't sufficient to model the Python lock type
 
15
 * because pth mutexes can be acquired multiple times by the
 
16
 * same thread.
 
17
 *
 
18
 * The pth_lock struct implements a Python lock as a "locked?" bit
 
19
 * and a <condition, mutex> pair.  In general, if the bit can be acquired
 
20
 * instantly, it is, else the pair is used to block the thread until the
 
21
 * bit is cleared.
 
22
 */
 
23
 
 
24
typedef struct {
 
25
        char             locked; /* 0=unlocked, 1=locked */
 
26
        /* a <cond, mutex> pair to handle an acquire of a locked lock */
 
27
        pth_cond_t   lock_released;
 
28
        pth_mutex_t  mut;
 
29
} pth_lock;
 
30
 
 
31
#define CHECK_STATUS(name)  if (status == -1) { printf("%d ", status); perror(name); error = 1; }
 
32
 
 
33
pth_attr_t PyThread_attr;
 
34
 
 
35
/*
 
36
 * Initialization.
 
37
 */
 
38
 
 
39
static void PyThread__init_thread(void)
 
40
{
 
41
        pth_init();
 
42
        PyThread_attr = pth_attr_new();
 
43
        pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);
 
44
        pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);
 
45
}
 
46
 
 
47
/*
 
48
 * Thread support.
 
49
 */
 
50
 
 
51
 
 
52
long PyThread_start_new_thread(void (*func)(void *), void *arg)
 
53
{
 
54
        pth_t th;
 
55
        dprintf(("PyThread_start_new_thread called\n"));
 
56
        if (!initialized)
 
57
                PyThread_init_thread();
 
58
 
 
59
        th = pth_spawn(PyThread_attr,
 
60
                                 (void* (*)(void *))func,
 
61
                                 (void *)arg
 
62
                                 );
 
63
 
 
64
        return th;
 
65
}
 
66
 
 
67
long PyThread_get_thread_ident(void)
 
68
{
 
69
        volatile pth_t threadid;
 
70
        if (!initialized)
 
71
                PyThread_init_thread();
 
72
        /* Jump through some hoops for Alpha OSF/1 */
 
73
        threadid = pth_self();
 
74
        return (long) *(long *) &threadid;
 
75
}
 
76
 
 
77
static void do_PyThread_exit_thread(int no_cleanup)
 
78
{
 
79
        dprintf(("PyThread_exit_thread called\n"));
 
80
        if (!initialized) {
 
81
                if (no_cleanup)
 
82
                        _exit(0);
 
83
                else
 
84
                        exit(0);
 
85
        }
 
86
}
 
87
 
 
88
void PyThread_exit_thread(void)
 
89
{
 
90
        do_PyThread_exit_thread(0);
 
91
}
 
92
 
 
93
void PyThread__exit_thread(void)
 
94
{
 
95
        do_PyThread_exit_thread(1);
 
96
}
 
97
 
 
98
#ifndef NO_EXIT_PROG
 
99
static void do_PyThread_exit_prog(int status, int no_cleanup)
 
100
{
 
101
        dprintf(("PyThread_exit_prog(%d) called\n", status));
 
102
        if (!initialized)
 
103
                if (no_cleanup)
 
104
                        _exit(status);
 
105
                else
 
106
                        exit(status);
 
107
}
 
108
 
 
109
void PyThread_exit_prog(int status)
 
110
{
 
111
        do_PyThread_exit_prog(status, 0);
 
112
}
 
113
 
 
114
void PyThread__exit_prog(int status)
 
115
{
 
116
        do_PyThread_exit_prog(status, 1);
 
117
}
 
118
#endif /* NO_EXIT_PROG */
 
119
 
 
120
/*
 
121
 * Lock support.
 
122
 */
 
123
PyThread_type_lock PyThread_allocate_lock(void)
 
124
{
 
125
        pth_lock *lock;
 
126
        int status, error = 0;
 
127
 
 
128
        dprintf(("PyThread_allocate_lock called\n"));
 
129
        if (!initialized)
 
130
                PyThread_init_thread();
 
131
 
 
132
        lock = (pth_lock *) malloc(sizeof(pth_lock));
 
133
        memset((void *)lock, '\0', sizeof(pth_lock));
 
134
        if (lock) {
 
135
                lock->locked = 0;
 
136
                status = pth_mutex_init(&lock->mut);
 
137
                CHECK_STATUS("pth_mutex_init");
 
138
                status = pth_cond_init(&lock->lock_released);
 
139
                CHECK_STATUS("pth_cond_init");
 
140
                if (error) {
 
141
                        free((void *)lock);
 
142
                        lock = NULL;
 
143
                }
 
144
        }
 
145
        dprintf(("PyThread_allocate_lock() -> %p\n", lock));
 
146
        return (PyThread_type_lock) lock;
 
147
}
 
148
 
 
149
void PyThread_free_lock(PyThread_type_lock lock)
 
150
{
 
151
        pth_lock *thelock = (pth_lock *)lock;
 
152
 
 
153
        dprintf(("PyThread_free_lock(%p) called\n", lock));
 
154
 
 
155
        free((void *)thelock);
 
156
}
 
157
 
 
158
int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
 
159
{
 
160
        int success;
 
161
        pth_lock *thelock = (pth_lock *)lock;
 
162
        int status, error = 0;
 
163
 
 
164
        dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
 
165
 
 
166
        status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);
 
167
        CHECK_STATUS("pth_mutex_acquire[1]");
 
168
        success = thelock->locked == 0;
 
169
        if (success) thelock->locked = 1;
 
170
        status = pth_mutex_release( &thelock->mut );
 
171
        CHECK_STATUS("pth_mutex_release[1]");
 
172
 
 
173
        if ( !success && waitflag ) {
 
174
                /* continue trying until we get the lock */
 
175
 
 
176
                /* mut must be locked by me -- part of the condition
 
177
                 * protocol */
 
178
                status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );
 
179
                CHECK_STATUS("pth_mutex_acquire[2]");
 
180
                while ( thelock->locked ) {
 
181
                        status = pth_cond_await(&thelock->lock_released,
 
182
                                                &thelock->mut, NULL);
 
183
                        CHECK_STATUS("pth_cond_await");
 
184
                }
 
185
                thelock->locked = 1;
 
186
                status = pth_mutex_release( &thelock->mut );
 
187
                CHECK_STATUS("pth_mutex_release[2]");
 
188
                success = 1;
 
189
        }
 
190
        if (error) success = 0;
 
191
        dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
 
192
        return success;
 
193
}
 
194
 
 
195
void PyThread_release_lock(PyThread_type_lock lock)
 
196
{
 
197
        pth_lock *thelock = (pth_lock *)lock;
 
198
        int status, error = 0;
 
199
 
 
200
        dprintf(("PyThread_release_lock(%p) called\n", lock));
 
201
 
 
202
        status = pth_mutex_acquire( &thelock->mut, 0, NULL );
 
203
        CHECK_STATUS("pth_mutex_acquire[3]");
 
204
 
 
205
        thelock->locked = 0;
 
206
 
 
207
        status = pth_mutex_release( &thelock->mut );
 
208
        CHECK_STATUS("pth_mutex_release[3]");
 
209
 
 
210
        /* wake up someone (anyone, if any) waiting on the lock */
 
211
        status = pth_cond_notify( &thelock->lock_released, 0 );
 
212
        CHECK_STATUS("pth_cond_notify");
 
213
}