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

Comparing cvsroot/EV-ADNS/ADNS.xs (file contents):
Revision 1.4 by root, Sat Dec 1 15:30:08 2007 UTC vs.
Revision 1.12 by root, Fri Dec 7 23:54:13 2007 UTC

4 4
5#include <poll.h> 5#include <poll.h>
6#include <adns.h> 6#include <adns.h>
7 7
8#include "EVAPI.h" 8#include "EVAPI.h"
9
10static HV *stash;
11static adns_state ads;
12 9
13struct ctx 10struct ctx
14{ 11{
15 SV *self; 12 SV *self;
16 adns_query query; 13 adns_query query;
17 SV *cb; 14 SV *cb;
18}; 15};
19 16
17static SV *
18ha2sv (adns_rr_hostaddr *rr)
19{
20 AV *av = newAV ();
21 av_push (av, newSVpv (rr->host, 0));
22 // TODO: add addresses
23
24 return newRV_noinc ((SV *)av);
25}
26
20static void 27static void
21process () 28process (adns_state ads)
22{ 29{
23 dSP; 30 dSP;
24 31
25 for (;;) 32 for (;;)
26 { 33 {
34 int i;
27 adns_query q = 0; 35 adns_query q = 0;
28 adns_answer *a; 36 adns_answer *a;
29 void *ctx; 37 void *ctx;
30 SV *cb; 38 SV *cb;
31 struct ctx *c; 39 struct ctx *c;
32 int r = adns_check (ads, &q, &a, &ctx); 40 int r = adns_check (ads, &q, &a, &ctx);
33 41
34 printf ("check %d\n", r);//D
35 if (r) 42 if (r)
36 break; 43 break;
37 44
38 c = (struct ctx *)ctx; 45 c = (struct ctx *)ctx;
39 cb = c->cb; 46 cb = c->cb;
40 c->cb = 0; 47 c->cb = 0;
41 ev_unref (); 48 ev_unref ();
49 SvREFCNT_dec (c->self);
50
51 PUSHMARK (SP);
52
53 EXTEND (SP, a->nrrs + 2);
54 PUSHs (sv_2mortal (newSViv (a->status)));
55 PUSHs (sv_2mortal (newSViv (a->expires)));
56
57 for (i = 0; i < a->nrrs; ++i)
58 {
59 SV *sv;
60
61 switch (a->type & adns_r_unknown ? adns_r_unknown : a->type)
62 {
63 case adns_r_ns_raw:
64 case adns_r_cname:
65 case adns_r_ptr:
66 case adns_r_ptr_raw:
67 sv = newSVpv (a->rrs.str [i], 0);
68 break;
69
70 case adns_r_txt:
71 {
72 AV *av = newAV ();
73 adns_rr_intstr *rr = a->rrs.manyistr [i];
74
75 while (rr->str)
76 {
77 av_push (av, newSVpvn (rr->str, rr->i));
78 ++rr;
79 }
80
81 sv = newRV_noinc ((SV *)av);
82 }
83 break;
84
85 case adns_r_a:
86 sv = newSVpv (inet_ntoa (a->rrs.inaddr [i]), 0);
87 break;
88
89 case adns_r_ns:
90 sv = ha2sv (a->rrs.hostaddr + i);
91 break;
92
93 case adns_r_hinfo:
94 {
95 /* untested */
96 AV *av = newAV ();
97 adns_rr_intstrpair *rr = a->rrs.intstrpair + i;
98
99 av_push (av, newSVpvn (rr->array [0].str, rr->array [0].i));
100 av_push (av, newSVpvn (rr->array [1].str, rr->array [1].i));
101
102 sv = newRV_noinc ((SV *)av);
103 }
104 break;
105
106 case adns_r_rp:
107 case adns_r_rp_raw:
108 {
109 /* untested */
110 AV *av = newAV ();
111 adns_rr_strpair *rr = a->rrs.strpair + i;
112
113 av_push (av, newSVpv (rr->array [0], 0));
114 av_push (av, newSVpv (rr->array [1], 0));
115
116 sv = newRV_noinc ((SV *)av);
117 }
118 break;
119
120 case adns_r_mx:
121 {
122 AV *av = newAV ();
123 adns_rr_inthostaddr *rr = a->rrs.inthostaddr + i;
124
125 av_push (av, newSViv (rr->i));
126 av_push (av, ha2sv (&rr->ha));
127
128 sv = newRV_noinc ((SV *)av);
129 }
130 break;
131
132 case adns_r_mx_raw:
133 {
134 AV *av = newAV ();
135 adns_rr_intstr *rr = a->rrs.intstr + i;
136
137 av_push (av, newSViv (rr->i));
138 av_push (av, newSVpv (rr->str, 0));
139
140 sv = newRV_noinc ((SV *)av);
141 }
142 break;
143
144 case adns_r_soa:
145 case adns_r_soa_raw:
146 {
147 AV *av = newAV ();
148 adns_rr_soa *rr = a->rrs.soa + i;
149
150 av_push (av, newSVpv (rr->mname, 0));
151 av_push (av, newSVpv (rr->rname, 0));
152 av_push (av, newSVuv (rr->serial));
153 av_push (av, newSVuv (rr->refresh));
154 av_push (av, newSVuv (rr->retry));
155 av_push (av, newSVuv (rr->expire));
156 av_push (av, newSVuv (rr->minimum));
157
158 sv = newRV_noinc ((SV *)av);
159 }
160 break;
161
162 case adns_r_srv_raw:
163 {
164 AV *av = newAV ();
165 adns_rr_srvraw *rr = a->rrs.srvraw + i;
166
167 av_push (av, newSViv (rr->priority));
168 av_push (av, newSViv (rr->weight));
169 av_push (av, newSViv (rr->port));
170 av_push (av, newSVpv (rr->host, 0));
171
172 sv = newRV_noinc ((SV *)av);
173 }
174 break;
175
176 case adns_r_srv:
177 {
178 AV *av = newAV ();
179 adns_rr_srvha *rr = a->rrs.srvha + i;
180
181 av_push (av, newSViv (rr->priority));
182 av_push (av, newSViv (rr->weight));
183 av_push (av, newSViv (rr->port));
184 av_push (av, ha2sv (&rr->ha));
185
186 sv = newRV_noinc ((SV *)av);
187 }
188 break;
189
190 case adns_r_unknown:
191 sv = newSVpvn (a->rrs.byteblock [i].data, a->rrs.byteblock [i].len);
192 break;
193
194 default:
195 case adns_r_addr:
196 sv = &PL_sv_undef; /* not supported */
197 break;
198 }
199
200 PUSHs (sv_2mortal (sv));
201 }
42 202
43 free (a); 203 free (a);
44 204
45 PUSHMARK (SP);
46 printf ("call %s\n", SvPV_nolen(cb));
47 PUTBACK; 205 PUTBACK;
48 call_sv (cb, G_VOID | G_DISCARD); 206 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
49 SPAGAIN; 207 SPAGAIN;
50 208
51 SvREFCNT_dec (cb); 209 SvREFCNT_dec (cb);
52 SvREFCNT_dec (c->self);
53 } 210 }
54} 211}
55 212
56static struct pollfd *fds; 213static struct pollfd *fds;
57static int nfd, mfd; 214static int nfd, mfd;
58static ev_io *iow; 215static ev_io *iow;
59static ev_timer tw; 216static ev_timer tw;
217static ev_idle iw;
60static ev_prepare prepare_ev; 218static ev_prepare pw;
61static struct timeval tv_now; 219static struct timeval tv_now;
62 220
63static void 221static void
64update_now (EV_P) 222update_now (EV_P)
65{ 223{
66 ev_tstamp t = ev_now (); 224 ev_tstamp t = ev_now ();
67 225
68 tv_now.tv_sec = (long)t; 226 tv_now.tv_sec = (long)t;
69 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6); 227 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e6);
228}
229
230static void
231idle_cb (EV_P_ ev_idle *w, int revents)
232{
233 ev_idle_stop (EV_A_ w);
70} 234}
71 235
72static void 236static void
73timer_cb (EV_P_ ev_timer *w, int revents) 237timer_cb (EV_P_ ev_timer *w, int revents)
74{ 238{
239 adns_state ads = (adns_state)w->data;
240 update_now ();
241
242 adns_processtimeouts (ads, &tv_now);
75} 243}
76 244
77static void 245static void
78io_cb (EV_P_ ev_io *w, int revents) 246io_cb (EV_P_ ev_io *w, int revents)
79{ 247{
248 adns_state ads = (adns_state)w->data;
80 update_now (EV_A); 249 update_now (EV_A);
81 250
82 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); 251 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
83 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); 252 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
84} 253}
87static void 256static void
88prepare_cb (EV_P_ ev_prepare *w, int revents) 257prepare_cb (EV_P_ ev_prepare *w, int revents)
89{ 258{
90 int i; 259 int i;
91 int timeout = 3600000; 260 int timeout = 3600000;
261 adns_state ads = (adns_state)w->data;
92 262
263 if (ev_is_active (&tw))
264 {
265 ev_ref ();
93 ev_timer_stop (EV_A_ &tw); 266 ev_timer_stop (EV_A_ &tw);
267 }
268
269 if (ev_is_active (&iw))
270 ev_idle_stop (EV_A_ &iw);
94 271
95 for (i = 0; i < nfd; ++i) 272 for (i = 0; i < nfd; ++i)
273 {
274 ev_ref ();
96 ev_io_stop (EV_A_ iow + i); 275 ev_io_stop (EV_A_ iow + i);
276 }
97 277
98 process (); 278 process (ads);
99
100 update_now (EV_A); 279 update_now (EV_A);
101 280
102 nfd = mfd; 281 nfd = mfd;
103 282
104 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now)) 283 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
105 { 284 {
106 mfd = nfd; 285 mfd = nfd;
107 286
287 free (iow); iow = malloc (mfd * sizeof (ev_io));
108 free (iow); iow = malloc (mfd * sizeof (struct pollfd)); 288 free (fds); fds = malloc (mfd * sizeof (struct pollfd));
109 free (fds); fds = malloc (mfd * sizeof (ev_io));
110 } 289 }
111
112 printf ("to %d\n", timeout);//d
113 290
114 ev_timer_set (&tw, timeout * 1e-3, 0.); 291 ev_timer_set (&tw, timeout * 1e-3, 0.);
115 ev_timer_start (EV_A_ &tw); 292 ev_timer_start (EV_A_ &tw);
293 ev_unref ();
116 294
117 // create one ev_io per pollfd 295 // create one ev_io per pollfd
118 for (i = 0; i < nfd; ++i) 296 for (i = 0; i < nfd; ++i)
119 { 297 {
120 ev_io_init (iow + i, io_cb, fds [i].fd, 298 ev_io_init (iow + i, io_cb, fds [i].fd,
121 ((fds [i].events & POLLIN ? EV_READ : 0) 299 ((fds [i].events & POLLIN ? EV_READ : 0)
122 | (fds [i].events & POLLOUT ? EV_WRITE : 0))); 300 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
123 301
124 ev_io_start (EV_A_ iow + i); 302 ev_io_start (EV_A_ iow + i);
303 ev_unref ();
125 } 304 }
126} 305}
306
307static HV *stash;
308static adns_state ads;
127 309
128MODULE = EV::ADNS PACKAGE = EV::ADNS 310MODULE = EV::ADNS PACKAGE = EV::ADNS
129 311
130PROTOTYPES: ENABLE 312PROTOTYPES: ENABLE
131 313
219 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 401 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
220 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 402 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
221 403
222 I_EV_API ("EV::ADNS"); 404 I_EV_API ("EV::ADNS");
223 405
224 ev_prepare_init (&prepare_ev, prepare_cb); ev_prepare_start (EV_DEFAULT_ &prepare_ev); 406 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
407
408 ev_prepare_init (&pw, prepare_cb);
409 pw.data = (void *)ads;
410 ev_prepare_start (EV_DEFAULT_ &pw);
225 ev_unref (); 411 ev_unref ();
226 412
413 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI);
414 iw.data = (void *)ads;
227 ev_init (&tw, timer_cb); 415 ev_init (&tw, timer_cb);
228 416 tw.data = (void *)ads;
229 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
230} 417}
231 418
232void submit (char *owner, int type, int flags, SV *cb) 419void submit (char *owner, int type, int flags, SV *cb)
233 PPCODE: 420 PPCODE:
234{ 421{
237 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query); 424 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query);
238 425
239 if (r) 426 if (r)
240 { 427 {
241 SvREFCNT_dec (csv); 428 SvREFCNT_dec (csv);
429 errno = r;
242 XSRETURN_EMPTY; 430 XSRETURN_EMPTY;
243 } 431 }
244 else 432 else
245 { 433 {
246 ev_ref (); 434 ev_ref ();
247 SvPOK_only (csv); 435 SvPOK_only (csv);
248 SvCUR_set (csv, sizeof (struct ctx)); 436 SvCUR_set (csv, sizeof (struct ctx));
437
249 c->self = csv; 438 c->self = csv;
250 c->cb = newSVsv (cb); 439 c->cb = newSVsv (cb);
251 440
441 if (!ev_is_active (&iw))
442 ev_idle_start (EV_A_ &iw);
443
252 if (GIMME_V != G_VOID) 444 if (GIMME_V != G_VOID)
253 { 445 {
254 csv = sv_2mortal (newRV_noinc (csv)); 446 csv = sv_2mortal (newRV_inc (csv));
255 sv_bless (csv, stash); 447 sv_bless (csv, stash);
256 XPUSHs (csv); 448 XPUSHs (csv);
257 } 449 }
258 } 450 }
259} 451}
260 452
261void DESTROY (SV *req) 453void DESTROY (SV *req)
454 ALIAS:
455 cancel = 1
262 CODE: 456 CODE:
263{ 457{
264 struct ctx *c; 458 struct ctx *c;
265 459
266 if (!(SvROK (req) && SvOBJECT (SvRV (req)) 460 if (!(SvROK (req) && SvOBJECT (SvRV (req))
270 c = (struct ctx *)SvPVX (SvRV (req)); 464 c = (struct ctx *)SvPVX (SvRV (req));
271 465
272 if (c->cb) 466 if (c->cb)
273 { 467 {
274 ev_unref (); 468 ev_unref ();
469 SvREFCNT_dec (c->cb);
470 c->cb = 0;
275 adns_cancel (c->query); 471 adns_cancel (c->query);
276 SvREFCNT_dec (c->cb); 472 SvREFCNT_dec (c->self);
277 } 473 }
278} 474}
279 475
280 476
281 477

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines