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.9 by root, Fri Jul 17 03:28:57 2009 UTC vs.
Revision 1.12 by root, Mon Nov 1 22:26:53 2010 UTC

10 10
11#include "EVAPI.h" 11#include "EVAPI.h"
12 12
13/* our userdata */ 13/* our userdata */
14typedef struct { 14typedef struct {
15 mutex_t lock; /* global loop lock */ 15 xmutex_t lock; /* global loop lock */
16 void (*signal_func) (void *signal_arg, int value); 16 void (*signal_func) (void *signal_arg, int value);
17 void *signal_arg; 17 void *signal_arg;
18 ev_async async_w; 18 ev_async async_w;
19 thread_t tid; 19 xthread_t tid;
20 unsigned int max_loops; 20 unsigned int max_loops;
21 unsigned int count; 21 unsigned int count;
22 22
23 cond_t invoke_cv; 23 xcond_t invoke_cv;
24 24
25 SV *interrupt; 25 SV *interrupt;
26#if defined(_WIN32) && defined(USE_ITHREADS)
27 void *thx;
28#endif
26} udat; 29} udat;
27 30
28static void loop_set_cb (EV_P); 31static void loop_set_cb (EV_P);
29 32
30static void 33static void
54 /* this is a bit tricky, but we can manage... */ 57 /* this is a bit tricky, but we can manage... */
55 u->count = 0; 58 u->count = 0;
56 59
57 ev_set_invoke_pending_cb (EV_A, fg_invoke_pending); 60 ev_set_invoke_pending_cb (EV_A, fg_invoke_pending);
58 ev_set_loop_release_cb (EV_A, 0, 0); 61 ev_set_loop_release_cb (EV_A, 0, 0);
59 ev_loop (EV_A, EVLOOP_NONBLOCK); 62 ev_run (EV_A, EVRUN_NOWAIT);
60 loop_set_cb (EV_A); 63 loop_set_cb (EV_A);
61 64
62 if (!u->count) 65 if (!u->count)
63 break; 66 break;
64 } 67 }
107} 110}
108 111
109X_THREAD_PROC(l_run) 112X_THREAD_PROC(l_run)
110{ 113{
111 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
112 124
113 l_acquire (EV_A); 125 l_acquire (EV_A);
114 126
115 /* yeah */ 127 /* yeah */
116 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); 128 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
117 129
118 ev_ref (EV_A); 130 ev_ref (EV_A);
119 ev_loop (EV_A, 0); 131 ev_run (EV_A, 0);
120 ev_unref (EV_A); 132 ev_unref (EV_A);
121 133
122 l_release (EV_A); 134 l_release (EV_A);
123 135
124 return 0; 136 return 0;
151 PUSHs (sv_2mortal (newSViv (PTR2IV (c_func)))); 163 PUSHs (sv_2mortal (newSViv (PTR2IV (c_func))));
152 PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop))))); 164 PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop)))));
153 165
154void 166void
155_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: @
156 CODE: 169 CODE:
157{ 170{
158 pthread_mutexattr_t ma; 171 pthread_mutexattr_t ma;
159 struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); 172 struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_));
160 udat *u; 173 udat *u;
161 174
162 Newz (0, u, 1, udat); 175 Newz (0, u, 1, udat);
163 u->interrupt = newSVsv (interrupt); 176 u->interrupt = newSVsv (interrupt);
164 u->signal_func = (void (*)(void *, int))sig_func; 177 u->signal_func = (void (*)(void *, int))sig_func;
165 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
166 182
167 ev_async_init (&u->async_w, async_cb); 183 ev_async_init (&u->async_w, async_cb);
168 ev_async_start (EV_A, &u->async_w); 184 ev_async_start (EV_A, &u->async_w);
169 185
170 pthread_mutexattr_init (&ma); 186 pthread_mutexattr_init (&ma);
187#ifdef PTHREAD_MUTEX_RECURSIVE
171 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
172 pthread_mutex_init (&u->lock, &ma); 192 pthread_mutex_init (&u->lock, &ma);
173 pthread_mutexattr_destroy (&ma); 193 pthread_mutexattr_destroy (&ma);
174 194
175 pthread_cond_init (&u->invoke_cv, 0); 195 pthread_cond_init (&u->invoke_cv, 0);
176 196
246 { 266 {
247 X_LOCK (u->lock); 267 X_LOCK (u->lock);
248 ev_async_stop (EV_A, &u->async_w); 268 ev_async_stop (EV_A, &u->async_w);
249 /* now thread is around blocking call, or in pthread_cond_wait */ 269 /* now thread is around blocking call, or in pthread_cond_wait */
250 pthread_cancel (u->tid); 270 pthread_cancel (u->tid);
271 X_UNLOCK (u->lock);
251 pthread_mutex_destroy (&u->lock); 272 pthread_mutex_destroy (&u->lock);
252 pthread_cond_destroy (&u->invoke_cv); 273 pthread_cond_destroy (&u->invoke_cv);
253 SvREFCNT_dec (u->interrupt); 274 SvREFCNT_dec (u->interrupt);
254 Safefree (u); 275 Safefree (u);
255 } 276 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines