… | |
… | |
37 | struct tctx |
37 | struct tctx |
38 | { |
38 | { |
39 | void *coro; |
39 | void *coro; |
40 | int wait_f; |
40 | int wait_f; |
41 | xcond_t acquire_c; |
41 | xcond_t acquire_c; |
|
|
42 | int jeret; |
42 | }; |
43 | }; |
43 | |
44 | |
44 | static struct tctx *tctx_free; |
45 | static struct tctx *tctx_free; |
45 | |
46 | |
46 | static struct tctx * |
47 | static struct tctx * |
… | |
… | |
108 | { |
109 | { |
109 | PERL_SET_CONTEXT (perl_thx); |
110 | PERL_SET_CONTEXT (perl_thx); |
110 | |
111 | |
111 | { |
112 | { |
112 | dTHX; /* inefficient, we already have perl_thx, but I see no better way */ |
113 | dTHX; /* inefficient, we already have perl_thx, but I see no better way */ |
|
|
114 | dJMPENV; |
113 | struct tctx *ctx; |
115 | struct tctx *ctx; |
|
|
116 | int catchret; |
114 | |
117 | |
115 | X_LOCK (release_m); |
118 | X_LOCK (release_m); |
116 | |
119 | |
117 | for (;;) |
120 | for (;;) |
118 | { |
121 | { |
… | |
… | |
134 | |
137 | |
135 | if (!ctx) /* timed out? */ |
138 | if (!ctx) /* timed out? */ |
136 | break; |
139 | break; |
137 | |
140 | |
138 | pthread_sigmask (SIG_SETMASK, &cursigset, 0); |
141 | pthread_sigmask (SIG_SETMASK, &cursigset, 0); |
|
|
142 | JMPENV_PUSH (ctx->jeret); |
139 | |
143 | |
|
|
144 | if (!ctx->jeret) |
140 | while (ctx->coro) |
145 | while (ctx->coro) |
141 | CORO_SCHEDULE; |
146 | CORO_SCHEDULE; |
142 | |
147 | |
|
|
148 | JMPENV_POP; |
143 | pthread_sigmask (SIG_SETMASK, &fullsigset, &cursigset); |
149 | pthread_sigmask (SIG_SETMASK, &fullsigset, &cursigset); |
144 | |
150 | |
145 | X_LOCK (acquire_m); |
151 | X_LOCK (acquire_m); |
146 | ctx->wait_f = 1; |
152 | ctx->wait_f = 1; |
147 | X_COND_SIGNAL (ctx->acquire_c); |
153 | X_COND_SIGNAL (ctx->acquire_c); |
… | |
… | |
200 | } |
206 | } |
201 | |
207 | |
202 | static void |
208 | static void |
203 | pmapi_acquire (void) |
209 | pmapi_acquire (void) |
204 | { |
210 | { |
|
|
211 | int jeret; |
205 | struct tctx *ctx = pthread_getspecific (current_key); |
212 | struct tctx *ctx = pthread_getspecific (current_key); |
206 | |
213 | |
207 | if (!ctx) |
214 | if (!ctx) |
208 | return; |
215 | return; |
209 | |
216 | |
… | |
… | |
214 | s_epipe_signal (&ep); |
221 | s_epipe_signal (&ep); |
215 | while (!ctx->wait_f) |
222 | while (!ctx->wait_f) |
216 | X_COND_WAIT (ctx->acquire_c, acquire_m); |
223 | X_COND_WAIT (ctx->acquire_c, acquire_m); |
217 | X_UNLOCK (acquire_m); |
224 | X_UNLOCK (acquire_m); |
218 | |
225 | |
|
|
226 | jeret = ctx->jeret; |
219 | tctx_put (ctx); |
227 | tctx_put (ctx); |
220 | pthread_sigmask (SIG_SETMASK, &cursigset, 0); |
228 | pthread_sigmask (SIG_SETMASK, &cursigset, 0); |
|
|
229 | |
|
|
230 | if (jeret) |
|
|
231 | JMPENV_JUMP (jeret); |
221 | } |
232 | } |
222 | |
233 | |
223 | static void |
234 | static void |
224 | set_thread_enable (pTHX_ void *arg) |
235 | set_thread_enable (pTHX_ void *arg) |
225 | { |
236 | { |