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

Comparing Coro/EV/EV.xs (file contents):
Revision 1.9 by root, Mon Dec 3 00:41:46 2007 UTC vs.
Revision 1.10 by root, Thu Dec 13 05:15:27 2007 UTC

1#include "EXTERN.h" 1#include "EXTERN.h"
2#include "perl.h" 2#include "perl.h"
3#include "XSUB.h" 3#include "XSUB.h"
4 4
5#include <stddef.h>
5#include <assert.h> 6#include <assert.h>
6#include <string.h> 7#include <string.h>
7 8
8#define EV_PROTOTYPES 0 9#define EV_PROTOTYPES 0
9#include "EVAPI.h" 10#include "EVAPI.h"
24static struct ev_prepare scheduler; 25static struct ev_prepare scheduler;
25static struct ev_idle idler; 26static struct ev_idle idler;
26static int inhibit; 27static int inhibit;
27 28
28static void 29static void
29idle_cb (struct ev_idle *w, int revents) 30idle_cb (EV_P_ ev_idle *w, int revents)
30{ 31{
31 ev_idle_stop (w); 32 ev_idle_stop (EV_A_ w);
32} 33}
33 34
34static void 35static void
35prepare_cb (struct ev_prepare *w, int revents) 36prepare_cb (EV_P_ ev_prepare *w, int revents)
36{ 37{
37 static int incede; 38 static int incede;
38 39
39 if (inhibit) 40 if (inhibit)
40 return; 41 return;
48 49
49 /* if still ready, then we have lower-priority coroutines. 50 /* if still ready, then we have lower-priority coroutines.
50 * poll anyways, but do not block. 51 * poll anyways, but do not block.
51 */ 52 */
52 if (CORO_NREADY >= incede && !ev_is_active (&idler)) 53 if (CORO_NREADY >= incede && !ev_is_active (&idler))
53 ev_idle_start (&idler); 54 ev_idle_start (EV_A_ &idler);
54 55
55 --incede; 56 --incede;
56} 57}
58
59/*****************************************************************************/
60
61typedef struct
62{
63 ev_io io;
64 ev_timer tw;
65 SV *done;
66 SV *current;
67} coro_dir;
68
69typedef struct
70{
71 coro_dir r, w;
72} coro_handle;
73
74
75static int
76handle_free (pTHX_ SV *sv, MAGIC *mg)
77{
78 coro_handle *data = (coro_handle *)mg->mg_ptr;
79 mg->mg_ptr = 0;
80
81 ev_io_stop (EV_DEFAULT_ &data->r.io); ev_io_stop (EV_DEFAULT_ &data->w.io);
82 ev_timer_stop (EV_DEFAULT_ &data->r.tw); ev_timer_stop (EV_DEFAULT_ &data->w.tw);
83 SvREFCNT_dec (data->r.done); SvREFCNT_dec (data->w.done);
84 SvREFCNT_dec (data->r.current); SvREFCNT_dec (data->w.current);
85
86 return 0;
87}
88
89static MGVTBL handle_vtbl = { 0, 0, 0, 0, handle_free };
90
91static void
92handle_cb (coro_dir *dir, int done)
93{
94 ev_io_stop (EV_A_ &dir->io);
95 ev_timer_stop (EV_A_ &dir->tw);
96
97 sv_setiv (dir->done, done);
98 SvREFCNT_dec (dir->done);
99 dir->done = 0;
100 CORO_READY (dir->current);
101 SvREFCNT_dec (dir->current);
102 dir->current = 0;
103}
104
105static void
106handle_io_cb (EV_P_ ev_io *w, int revents)
107{
108 handle_cb ((coro_dir *)(((char *)w) - offsetof (coro_dir, io)), 1);
109}
110
111static void
112handle_timer_cb (EV_P_ ev_timer *w, int revents)
113{
114 handle_cb ((coro_dir *)(((char *)w) - offsetof (coro_dir, tw)), 0);
115}
116
117/*****************************************************************************/
57 118
58MODULE = Coro::EV PACKAGE = Coro::EV 119MODULE = Coro::EV PACKAGE = Coro::EV
59 120
60PROTOTYPES: ENABLE 121PROTOTYPES: ENABLE
61 122
63{ 124{
64 I_EV_API ("Coro::EV"); 125 I_EV_API ("Coro::EV");
65 I_CORO_API ("Coro::Event"); 126 I_CORO_API ("Coro::Event");
66 127
67 ev_prepare_init (&scheduler, prepare_cb); 128 ev_prepare_init (&scheduler, prepare_cb);
129 ev_set_priority (&scheduler, EV_MINPRI);
68 ev_prepare_start (EV_DEFAULT_ &scheduler); 130 ev_prepare_start (EV_DEFAULT_ &scheduler);
69 ev_unref (); 131 ev_unref ();
70 132
71 ev_idle_init (&idler, idle_cb); 133 ev_idle_init (&idler, idle_cb);
134 ev_set_priority (&idler, EV_MINPRI);
72} 135}
73 136
74void 137void
75_loop_oneshot () 138_loop_oneshot ()
76 CODE: 139 CODE:
108 (void *)SvREFCNT_inc (av) 171 (void *)SvREFCNT_inc (av)
109 ); 172 );
110 ONCE_DONE; 173 ONCE_DONE;
111} 174}
112 175
176void
177_readable_ev (SV *handle_sv, SV *done_sv)
178 ALIAS:
179 _writable_ev = 1
180 CODE:
181{
182 AV *handle = (AV *)SvRV (handle_sv);
183 SV *data_sv = AvARRAY (handle)[5];
184 coro_handle *data;
185 coro_dir *dir;
186 assert (AvFILLp (handle) >= 7);
113 187
188 if (!SvOK (data_sv))
189 {
190 int fno = sv_fileno (AvARRAY (handle)[0]);
191 data_sv = AvARRAY (handle)[5] = NEWSV (0, sizeof (coro_handle));
192 SvPOK_only (data_sv);
193 SvREADONLY_on (data_sv);
194 data = (coro_handle *)SvPVX (data_sv);
195 memset (data, 0, sizeof (coro_handle));
114 196
197 ev_io_init (&data->r.io, handle_io_cb, fno, EV_READ);
198 ev_io_init (&data->w.io, handle_io_cb, fno, EV_WRITE);
199 ev_init (&data->r.tw, handle_timer_cb);
200 ev_init (&data->w.tw, handle_timer_cb);
201
202 sv_magicext (data_sv, 0, PERL_MAGIC_ext, &handle_vtbl, (char *)data, 0);
203 }
204 else
205 data = (coro_handle *)SvPVX (data_sv);
206
207 dir = ix ? &data->w : &data->r;
208
209 if (ev_is_active (&dir->io) || ev_is_active (&dir->tw))
210 croak ("recursive invocation of readable_ev or writable_ev");
211
212 dir->done = SvREFCNT_inc (done_sv);
213 dir->current = SvREFCNT_inc (CORO_CURRENT);
214
215 {
216 SV *to = AvARRAY (handle)[2];
217
218 if (SvOK (to))
219 {
220 ev_timer_set (&dir->tw, 0., SvNV (to));
221 ev_timer_start (EV_DEFAULT_ &dir->tw);
222 }
223 }
224
225 ev_io_start (EV_DEFAULT_ &dir->io);
226}
227

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines