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

Comparing Coro/Event/Event.xs (file contents):
Revision 1.3 by root, Fri Aug 17 01:45:39 2001 UTC vs.
Revision 1.4 by root, Fri Aug 17 03:33:00 2001 UTC

7#include "EventAPI.h" 7#include "EventAPI.h"
8#include "../Coro/CoroAPI.h" 8#include "../Coro/CoroAPI.h"
9 9
10#define CD_CORO 0 10#define CD_CORO 0
11#define CD_TYPE 1 11#define CD_TYPE 1
12#define CD_W 2 12#define CD_OK 2
13#define CD_GOT 3 13#define CD_GOT 3 /* hardcoded in Coro::Event, Coro::Handle */
14#define CD_MAX 3 14#define CD_MAX 3
15/* no support for hits and prio so far. */ 15/* no support for hits and prio so far. */
16 16
17#define EV_CLASS "Coro::Event::Ev" 17#define EV_CLASS "Coro::Event"
18 18
19static HV *ev_stash;
20static pe_idle *scheduler; 19static pe_idle *scheduler;
21static int do_schedule; 20static int do_schedule;
22 21
23#define NEED_SCHEDULE if (!do_schedule) \ 22#define NEED_SCHEDULE if (!do_schedule) \
24 { \ 23 { \
25 do_schedule = 1; \ 24 do_schedule = 1; \
26 GEventAPI->now ((pe_watcher *)scheduler); \ 25 GEventAPI->now ((pe_watcher *)scheduler); \
27 } 26 }
27
28static void 28static void
29coro_std_cb(pe_event *pe) 29coro_std_cb(pe_event *pe)
30{ 30{
31 AV *av = (AV *)SvRV ((SV *)pe->ext_data); 31 AV *priv = (AV *)SvRV ((SV *)pe->ext_data);
32 IV type = SvIV (*av_fetch (av, CD_TYPE, 1)); 32 IV type = SvIV (*av_fetch (priv, CD_TYPE, 1));
33 SV *cd_coro = *av_fetch (av, CD_CORO, 1); 33 SV *cd_coro = *av_fetch (priv, CD_CORO, 1);
34
35 av_store (av, CD_W, SvREFCNT_inc (pe->up->mysv));
36 34
37 if (type == 1) 35 if (type == 1)
38 av_store (av, CD_GOT, newSViv (((pe_ioevent *)pe)->got)); 36 av_store (priv, CD_GOT, newSViv (((pe_ioevent *)pe)->got));
39
40 GEventAPI->stop (pe->up, 0);
41 37
42 if (SvROK (cd_coro)) 38 if (SvROK (cd_coro))
43 { 39 {
44 CORO_READY (cd_coro); 40 CORO_READY (cd_coro);
41 av_store (priv, CD_CORO, &PL_sv_undef);
45 NEED_SCHEDULE; 42 NEED_SCHEDULE;
43 }
44 else
45 {
46 av_store (priv, CD_OK, &PL_sv_yes);
47 GEventAPI->stop (pe->up, 0);
46 } 48 }
47} 49}
48 50
49static void 51static void
50scheduler_cb(pe_event *pe) 52scheduler_cb(pe_event *pe)
62BOOT: 64BOOT:
63{ 65{
64 I_EVENT_API("Coro::Event"); 66 I_EVENT_API("Coro::Event");
65 I_CORO_API ("Coro::Event"); 67 I_CORO_API ("Coro::Event");
66 68
67 ev_stash = gv_stashpv (EV_CLASS, TRUE);
68
69 /* create a fake idle handler (we only ever call now) */ 69 /* create a fake idle handler (we only ever call now) */
70 scheduler = GEventAPI->new_idle (0, 0); 70 scheduler = GEventAPI->new_idle (0, 0);
71 scheduler->base.callback = scheduler_cb; 71 scheduler->base.callback = scheduler_cb;
72 scheduler->min_interval = newSVnv (0); 72 scheduler->min_interval = newSVnv (0);
73 scheduler->max_interval = newSVnv (0); 73 scheduler->max_interval = newSVnv (0);
79 SV * self 79 SV * self
80 int type 80 int type
81 CODE: 81 CODE:
82 pe_watcher *w = GEventAPI->sv_2watcher (self); 82 pe_watcher *w = GEventAPI->sv_2watcher (self);
83 AV *priv = newAV (); 83 AV *priv = newAV ();
84 SV *rv; 84 SV *rv = newRV_noinc ((SV *)priv);
85 85
86 av_extend (priv, CD_MAX); 86 av_extend (priv, CD_MAX);
87 av_store (priv, CD_TYPE, newSViv (type)); 87 av_store (priv, CD_TYPE, newSViv (type));
88 88
89 rv = sv_bless (newRV_noinc ((SV *)priv), ev_stash); 89 w->callback = coro_std_cb;
90 w->ext_data = rv;
90 91
91 hv_store ((HV *)SvRV (self), 92 hv_store ((HV *)SvRV (self),
92 EV_CLASS, strlen (EV_CLASS), 93 EV_CLASS, strlen (EV_CLASS),
93 rv, 0); 94 rv, 0);
94 95
95 w->ext_data = rv;
96 w->callback = coro_std_cb;
97
98void 96void
99_next0(self) 97_next(self)
100 SV * self 98 SV * self
101 CODE: 99 CODE:
102 pe_watcher *w = GEventAPI->sv_2watcher (self); 100 pe_watcher *w = GEventAPI->sv_2watcher (self);
103 AV *priv = (AV *)SvRV ((SV *)w->ext_data); 101 AV *priv = (AV *)SvRV ((SV *)w->ext_data);
104 102
105 GEventAPI->start (w, 1);
106
107 if (SvROK (*av_fetch (priv, CD_CORO, 1))) 103 if (SvOK (*av_fetch (priv, CD_CORO, 1)))
108 croak ("only one coroutine can wait for an event"); 104 croak ("only one coroutine can wait for an event");
109 105
110 av_store (priv, CD_CORO, SvREFCNT_inc (CORO_CURRENT)); 106 if (!w->running)
107 GEventAPI->start (w, 1);
111 108
112SV * 109 if (*av_fetch (priv, CD_OK, 1) == &PL_sv_yes)
113_next1(self) 110 {
114 SV * self 111 av_store (priv, CD_OK, &PL_sv_no);
115 CODE: 112 XSRETURN_NO;
116 pe_watcher *w = GEventAPI->sv_2watcher (self); 113 }
117 AV *priv = (AV *)SvRV ((SV *)w->ext_data); 114 else
115 {
116 av_store (priv, CD_CORO, SvREFCNT_inc (CORO_CURRENT));
117 XSRETURN_YES;
118 }
118 119
119 av_store (priv, CD_CORO, &PL_sv_undef);
120
121 RETVAL = SvREFCNT_inc ((SV *)w->ext_data);
122 OUTPUT:
123 RETVAL
124

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines