… | |
… | |
16 | thread_t tid; |
16 | thread_t tid; |
17 | |
17 | |
18 | cond_t invoke_cv; |
18 | cond_t invoke_cv; |
19 | mutex_t invoke_mutex; |
19 | mutex_t invoke_mutex; |
20 | |
20 | |
21 | SV *asy; |
21 | SV *interrupt; |
22 | } udat; |
22 | } udat; |
23 | |
23 | |
24 | static void |
24 | static void |
25 | c_func (pTHX_ void *loop_, int value) |
25 | c_func (pTHX_ void *loop_, int value) |
26 | { |
26 | { |
… | |
… | |
57 | { |
57 | { |
58 | udat *u = ev_userdata (EV_A); |
58 | udat *u = ev_userdata (EV_A); |
59 | X_UNLOCK (u->lock); |
59 | X_UNLOCK (u->lock); |
60 | u->signal_func (u->signal_arg, 1); |
60 | u->signal_func (u->signal_arg, 1); |
61 | X_COND_WAIT (u->invoke_cv, u->invoke_mutex); |
61 | X_COND_WAIT (u->invoke_cv, u->invoke_mutex); |
62 | fprintf (stderr, "invoke2\n");//D |
|
|
63 | X_LOCK (u->lock); |
62 | X_LOCK (u->lock); |
64 | } |
63 | } |
65 | |
64 | |
66 | X_THREAD_PROC(l_run) |
65 | X_THREAD_PROC(l_run) |
67 | { |
66 | { |
… | |
… | |
72 | X_LOCK (u->lock); |
71 | X_LOCK (u->lock); |
73 | ev_ref (loop); /* really? */ |
72 | ev_ref (loop); /* really? */ |
74 | for (;;) /* really? */ |
73 | for (;;) /* really? */ |
75 | ev_loop (loop, 0); |
74 | ev_loop (loop, 0); |
76 | X_UNLOCK (u->lock); |
75 | X_UNLOCK (u->lock); |
|
|
76 | } |
|
|
77 | |
|
|
78 | static void |
|
|
79 | scope_lock_cb (pTHX_ void *loop_) |
|
|
80 | { |
|
|
81 | struct ev_loop *loop = (struct ev_loop *)SvIVX ((SV *)loop_); |
|
|
82 | udat *u = ev_userdata (loop); |
|
|
83 | |
|
|
84 | X_UNLOCK (u->lock); |
|
|
85 | SvREFCNT_dec ((SV *)loop_); |
77 | } |
86 | } |
78 | |
87 | |
79 | MODULE = EV::Loop::Async PACKAGE = EV::Loop::Async |
88 | MODULE = EV::Loop::Async PACKAGE = EV::Loop::Async |
80 | |
89 | |
81 | PROTOTYPES: ENABLE |
90 | PROTOTYPES: ENABLE |
… | |
… | |
91 | EXTEND (SP, 2); |
100 | EXTEND (SP, 2); |
92 | PUSHs (sv_2mortal (newSViv (PTR2IV (c_func)))); |
101 | PUSHs (sv_2mortal (newSViv (PTR2IV (c_func)))); |
93 | PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop))))); |
102 | PUSHs (sv_2mortal (newSViv (SvIVX (SvRV (loop))))); |
94 | |
103 | |
95 | void |
104 | void |
96 | _attach (SV *loop_, SV *asy, IV sig_func, IV sig_arg) |
105 | _attach (SV *loop_, SV *interrupt, IV sig_func, void *sig_arg) |
97 | CODE: |
106 | CODE: |
98 | { |
107 | { |
99 | pthread_mutexattr_t ma; |
108 | pthread_mutexattr_t ma; |
100 | struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); |
109 | struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); |
101 | udat *u; |
110 | udat *u; |
102 | printf ("f,a %p,%p\n", sig_func, sig_arg);//D |
|
|
103 | |
111 | |
104 | Newz (0, u, 1, udat); |
112 | Newz (0, u, 1, udat); |
105 | u->asy = newSVsv (asy); |
113 | u->interrupt = newSVsv (interrupt); |
106 | u->signal_func = (void (*)(void *, int))sig_func; |
114 | u->signal_func = (void (*)(void *, int))sig_func; |
107 | u->signal_arg = sig_arg; |
115 | u->signal_arg = sig_arg; |
108 | |
116 | |
109 | ev_async_init (&u->async_w, async_cb); |
117 | ev_async_init (&u->async_w, async_cb); |
110 | ev_async_start (loop, &u->async_w); |
118 | ev_async_start (loop, &u->async_w); |
… | |
… | |
119 | |
127 | |
120 | ev_set_userdata (loop, u); |
128 | ev_set_userdata (loop, u); |
121 | ev_set_invoke_pending_cb (loop, l_invoke); |
129 | ev_set_invoke_pending_cb (loop, l_invoke); |
122 | ev_set_loop_release_cb (loop, l_release, l_acquire); |
130 | ev_set_loop_release_cb (loop, l_release, l_acquire); |
123 | |
131 | |
124 | X_LOCK (u->lock); |
|
|
125 | thread_create (&u->tid, l_run, (void *)loop); |
132 | thread_create (&u->tid, l_run, (void *)loop); |
126 | } |
133 | } |
|
|
134 | |
|
|
135 | SV * |
|
|
136 | interrupt (SV *loop_) |
|
|
137 | CODE: |
|
|
138 | { |
|
|
139 | struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); |
|
|
140 | udat *u = ev_userdata (loop); |
|
|
141 | |
|
|
142 | RETVAL = newSVsv (u->interrupt); |
|
|
143 | } |
|
|
144 | OUTPUT: |
|
|
145 | RETVAL |
127 | |
146 | |
128 | void |
147 | void |
129 | lock (SV *loop_) |
148 | lock (SV *loop_) |
130 | ALIAS: |
149 | ALIAS: |
131 | lock = 0 |
150 | lock = 0 |
… | |
… | |
140 | { |
159 | { |
141 | case 0: X_LOCK (u->lock); break; |
160 | case 0: X_LOCK (u->lock); break; |
142 | case 1: X_UNLOCK (u->lock); break; |
161 | case 1: X_UNLOCK (u->lock); break; |
143 | case 2: ev_async_send (loop, &u->async_w); break; |
162 | case 2: ev_async_send (loop, &u->async_w); break; |
144 | } |
163 | } |
|
|
164 | } |
|
|
165 | |
|
|
166 | void |
|
|
167 | scope_lock (SV *loop_) |
|
|
168 | CODE: |
|
|
169 | { |
|
|
170 | struct ev_loop *loop = (struct ev_loop *)SvIVX (SvRV (loop_)); |
|
|
171 | udat *u = ev_userdata (loop); |
|
|
172 | |
|
|
173 | X_LOCK (u->lock); |
|
|
174 | |
|
|
175 | LEAVE; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
|
|
176 | SAVEDESTRUCTOR_X (scope_lock_cb, (void *)SvREFCNT_inc (SvRV (loop_))); |
|
|
177 | ENTER; /* unfortunately, perl sandwiches XS calls into ENTER/LEAVE */ |
145 | } |
178 | } |
146 | |
179 | |
147 | void |
180 | void |
148 | DESTROY (SV *loop_) |
181 | DESTROY (SV *loop_) |
149 | CODE: |
182 | CODE: |
… | |
… | |
159 | ev_async_stop (loop, &u->async_w); |
192 | ev_async_stop (loop, &u->async_w); |
160 | pthread_mutex_destroy (&u->lock); |
193 | pthread_mutex_destroy (&u->lock); |
161 | pthread_cond_destroy (&u->invoke_cv); |
194 | pthread_cond_destroy (&u->invoke_cv); |
162 | pthread_mutex_destroy (&u->invoke_mutex); |
195 | pthread_mutex_destroy (&u->invoke_mutex); |
163 | Safefree (u); |
196 | Safefree (u); |
164 | SvREFCNT_dec (u->asy); |
197 | SvREFCNT_dec (u->interrupt); |
165 | } |
198 | } |
166 | } |
199 | } |
167 | |
200 | |
168 | |
201 | |
169 | |
202 | |