ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Loop-Async/Async.xs
(Generate patch)

Comparing EV-Loop-Async/Async.xs (file contents):
Revision 1.8 by root, Fri Jul 17 02:52:22 2009 UTC vs.
Revision 1.12 by root, Mon Nov 1 22:26:53 2010 UTC

1#include "xthread.h" 1#include "xthread.h"
2
3#include <errno.h>
2 4
3#include "EXTERN.h" 5#include "EXTERN.h"
4#include "perl.h" 6#include "perl.h"
5#include "XSUB.h" 7#include "XSUB.h"
6 8
8 10
9#include "EVAPI.h" 11#include "EVAPI.h"
10 12
11/* our userdata */ 13/* our userdata */
12typedef struct { 14typedef struct {
13 mutex_t lock; /* global loop lock */ 15 xmutex_t lock; /* global loop lock */
14 void (*signal_func) (void *signal_arg, int value); 16 void (*signal_func) (void *signal_arg, int value);
15 void *signal_arg; 17 void *signal_arg;
16 ev_async async_w; 18 ev_async async_w;
17 thread_t tid; 19 xthread_t tid;
18 unsigned int max_loops; 20 unsigned int max_loops;
19 unsigned int count; 21 unsigned int count;
20 22
21 cond_t invoke_cv; 23 xcond_t invoke_cv;
22 24
23 SV *interrupt; 25 SV *interrupt;
26#if defined(_WIN32) && defined(USE_ITHREADS)
27 void *thx;
28#endif
24} udat; 29} udat;
25 30
26static void loop_set_cb (EV_P); 31static void loop_set_cb (EV_P);
27 32
28static void 33static void
52 /* this is a bit tricky, but we can manage... */ 57 /* this is a bit tricky, but we can manage... */
53 u->count = 0; 58 u->count = 0;
54 59
55 ev_set_invoke_pending_cb (EV_A, fg_invoke_pending); 60 ev_set_invoke_pending_cb (EV_A, fg_invoke_pending);
56 ev_set_loop_release_cb (EV_A, 0, 0); 61 ev_set_loop_release_cb (EV_A, 0, 0);
57 ev_loop (EV_A, EVLOOP_NONBLOCK); 62 ev_run (EV_A, EVRUN_NOWAIT);
58 loop_set_cb (EV_A); 63 loop_set_cb (EV_A);
59 64
60 if (!u->count) 65 if (!u->count)
61 break; 66 break;
62 } 67 }
105} 110}
106 111
107X_THREAD_PROC(l_run) 112X_THREAD_PROC(l_run)
108{ 113{
109 struct ev_loop *loop = (struct ev_loop *)thr_arg; 114 struct ev_loop *loop = (struct ev_loop *)thr_arg;
115#if defined(_WIN32) && defined(USE_ITHREADS)
116 udat *u = ev_userdata (EV_A);
117
118 /* just setting the same context pointer as the other thread is */
119 /* probably fatal, yet, I have no clue what makes libev crash (malloc?) */
120 /* as visual c also crashes when it tries to debug the crash */
121 /* the loser platform is indeed a crashy OS */
122 PERL_SET_CONTEXT (u->thx);
123#endif
110 124
111 l_acquire (EV_A); 125 l_acquire (EV_A);
112 126
113 /* yeah */ 127 /* yeah */
114 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); 128 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
115 129
116 ev_ref (EV_A); 130 ev_ref (EV_A);
117 ev_loop (EV_A, 0); 131 ev_run (EV_A, 0);
118 ev_unref (EV_A); 132 ev_unref (EV_A);
119 133
120 l_release (EV_A); 134 l_release (EV_A);
121 135
122 return 0; 136 return 0;
149 PUSHs (sv_2mortal (newSViv (PTR2IV (c_func)))); 163 PUSHs (sv_2mortal (newSViv (PTR2IV (c_func))));
150 PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop))))); 164 PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop)))));
151 165
152void 166void
153_attach (SV *loop_, SV *interrupt, IV sig_func, void *sig_arg) 167_attach (SV *loop_, SV *interrupt, IV sig_func, void *sig_arg)
168 PROTOTYPE: @
154 CODE: 169 CODE:
155{ 170{
156 pthread_mutexattr_t ma; 171 pthread_mutexattr_t ma;
157 struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); 172 struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_));
158 udat *u; 173 udat *u;
159 174
160 Newz (0, u, 1, udat); 175 Newz (0, u, 1, udat);
161 u->interrupt = newSVsv (interrupt); 176 u->interrupt = newSVsv (interrupt);
162 u->signal_func = (void (*)(void *, int))sig_func; 177 u->signal_func = (void (*)(void *, int))sig_func;
163 u->signal_arg = sig_arg; 178 u->signal_arg = sig_arg;
179#if defined(_WIN32) && defined(USE_ITHREADS)
180 u->thx = PERL_GET_CONTEXT;
181#endif
164 182
165 ev_async_init (&u->async_w, async_cb); 183 ev_async_init (&u->async_w, async_cb);
166 ev_async_start (EV_A, &u->async_w); 184 ev_async_start (EV_A, &u->async_w);
167 185
168 pthread_mutexattr_init (&ma); 186 pthread_mutexattr_init (&ma);
187#ifdef PTHREAD_MUTEX_RECURSIVE
169 pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE); 188 pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE);
189#else
190 pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE_NP);
191#endif
170 pthread_mutex_init (&u->lock, &ma); 192 pthread_mutex_init (&u->lock, &ma);
171 pthread_mutexattr_destroy (&ma); 193 pthread_mutexattr_destroy (&ma);
172 194
173 pthread_cond_init (&u->invoke_cv, 0); 195 pthread_cond_init (&u->invoke_cv, 0);
174 196
244 { 266 {
245 X_LOCK (u->lock); 267 X_LOCK (u->lock);
246 ev_async_stop (EV_A, &u->async_w); 268 ev_async_stop (EV_A, &u->async_w);
247 /* now thread is around blocking call, or in pthread_cond_wait */ 269 /* now thread is around blocking call, or in pthread_cond_wait */
248 pthread_cancel (u->tid); 270 pthread_cancel (u->tid);
271 X_UNLOCK (u->lock);
249 pthread_mutex_destroy (&u->lock); 272 pthread_mutex_destroy (&u->lock);
250 pthread_cond_destroy (&u->invoke_cv); 273 pthread_cond_destroy (&u->invoke_cv);
251 SvREFCNT_dec (u->interrupt); 274 SvREFCNT_dec (u->interrupt);
252 Safefree (u); 275 Safefree (u);
253 } 276 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines