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.3 by root, Sat Dec 1 14:37:46 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; 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);
36 44
37 c = (struct ctx *)ctx; 45 c = (struct ctx *)ctx;
38 cb = c->cb; 46 cb = c->cb;
39 c->cb = 0; 47 c->cb = 0;
40 ev_unref (); 48 ev_unref ();
49 SvREFCNT_dec (c->self);
41 50
42 PUSHMARK (SP); 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 }
202
203 free (a);
204
205 PUTBACK;
43 call_sv (cb, G_VOID | G_DISCARD | G_EVAL); 206 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
207 SPAGAIN;
44 208
45 SvREFCNT_dec (cb); 209 SvREFCNT_dec (cb);
46 } 210 }
47} 211}
48 212
49static struct pollfd *fds; 213static struct pollfd *fds;
50static int nfd; 214static int nfd, mfd;
51static ev_io *iow; 215static ev_io *iow;
52static ev_timer tw; 216static ev_timer tw;
217static ev_idle iw;
53static ev_prepare prepare_ev; 218static ev_prepare pw;
54static struct timeval tv_now; 219static struct timeval tv_now;
55 220
56static void 221static void
57update_now (EV_P) 222update_now (EV_P)
58{ 223{
59 ev_tstamp t = ev_now (); 224 ev_tstamp t = ev_now ();
60 225
61 tv_now.tv_sec = (long)t; 226 tv_now.tv_sec = (long)t;
62 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);
63} 234}
64 235
65static void 236static void
66timer_cb (EV_P_ ev_timer *w, int revents) 237timer_cb (EV_P_ ev_timer *w, int revents)
67{ 238{
239 adns_state ads = (adns_state)w->data;
240 update_now ();
241
242 adns_processtimeouts (ads, &tv_now);
68} 243}
69 244
70static void 245static void
71io_cb (EV_P_ ev_io *w, int revents) 246io_cb (EV_P_ ev_io *w, int revents)
72{ 247{
248 adns_state ads = (adns_state)w->data;
73 update_now (EV_A); 249 update_now (EV_A);
74 250
75 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); 251 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
76 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); 252 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
77} 253}
80static void 256static void
81prepare_cb (EV_P_ ev_prepare *w, int revents) 257prepare_cb (EV_P_ ev_prepare *w, int revents)
82{ 258{
83 int i; 259 int i;
84 int timeout = 3600000; 260 int timeout = 3600000;
261 adns_state ads = (adns_state)w->data;
85 262
263 if (ev_is_active (&tw))
264 {
265 ev_ref ();
86 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);
87 271
88 for (i = 0; i < nfd; ++i) 272 for (i = 0; i < nfd; ++i)
273 {
274 ev_ref ();
89 ev_io_stop (EV_A_ iow + i); 275 ev_io_stop (EV_A_ iow + i);
276 }
90 277
91 process (); 278 process (ads);
92
93 update_now (EV_A); 279 update_now (EV_A);
280
281 nfd = mfd;
94 282
95 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now)) 283 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
96 { 284 {
285 mfd = nfd;
286
287 free (iow); iow = malloc (mfd * sizeof (ev_io));
97 free (iow); iow = malloc (nfd * sizeof (struct pollfd)); 288 free (fds); fds = malloc (mfd * sizeof (struct pollfd));
98 free (fds); fds = malloc (nfd * sizeof (ev_io));
99 } 289 }
100 290
101 ev_timer_set (&tw, timeout * 1e-3, 0.); 291 ev_timer_set (&tw, timeout * 1e-3, 0.);
102 ev_timer_start (EV_A_ &tw); 292 ev_timer_start (EV_A_ &tw);
293 ev_unref ();
103 294
104 // create on ev_io per pollfd 295 // create one ev_io per pollfd
105 for (i = 0; i < nfd; ++i) 296 for (i = 0; i < nfd; ++i)
106 { 297 {
107 ev_io_init (iow + i, io_cb, fds [i].fd, 298 ev_io_init (iow + i, io_cb, fds [i].fd,
108 ((fds [i].events & POLLIN ? EV_READ : 0) 299 ((fds [i].events & POLLIN ? EV_READ : 0)
109 | (fds [i].events & POLLOUT ? EV_WRITE : 0))); 300 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
110 301
111 ev_io_start (EV_A_ iow + i); 302 ev_io_start (EV_A_ iow + i);
303 ev_unref ();
112 } 304 }
113} 305}
306
307static HV *stash;
308static adns_state ads;
114 309
115MODULE = EV::ADNS PACKAGE = EV::ADNS 310MODULE = EV::ADNS PACKAGE = EV::ADNS
116 311
117PROTOTYPES: ENABLE 312PROTOTYPES: ENABLE
118 313
206 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; )
207 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 402 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
208 403
209 I_EV_API ("EV::ADNS"); 404 I_EV_API ("EV::ADNS");
210 405
211 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);
212 ev_unref (); 411 ev_unref ();
213 412
413 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI);
414 iw.data = (void *)ads;
214 ev_init (&tw, timer_cb); 415 ev_init (&tw, timer_cb);
215 416 tw.data = (void *)ads;
216 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
217} 417}
218 418
219void submit (char *owner, int type, int flags, SV *cb) 419void submit (char *owner, int type, int flags, SV *cb)
220 PPCODE: 420 PPCODE:
221{ 421{
223 struct ctx *c = (struct ctx *)SvPVX (csv); 423 struct ctx *c = (struct ctx *)SvPVX (csv);
224 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);
225 425
226 if (r) 426 if (r)
227 { 427 {
228 printf ("errn %d\n", r);//D
229 SvREFCNT_dec (csv); 428 SvREFCNT_dec (csv);
429 errno = r;
230 XSRETURN_EMPTY; 430 XSRETURN_EMPTY;
231 } 431 }
232 else 432 else
233 { 433 {
234 ev_ref (); 434 ev_ref ();
235 SvPOK_only (csv); 435 SvPOK_only (csv);
236 SvCUR_set (csv, sizeof (struct ctx)); 436 SvCUR_set (csv, sizeof (struct ctx));
437
237 c->self = csv; 438 c->self = csv;
238 c->cb = newSVsv (cb); 439 c->cb = newSVsv (cb);
440
441 if (!ev_is_active (&iw))
442 ev_idle_start (EV_A_ &iw);
239 443
240 if (GIMME_V != G_VOID) 444 if (GIMME_V != G_VOID)
241 { 445 {
242 csv = sv_2mortal (newRV_inc (csv)); 446 csv = sv_2mortal (newRV_inc (csv));
243 sv_bless (csv, stash); 447 sv_bless (csv, stash);
245 } 449 }
246 } 450 }
247} 451}
248 452
249void DESTROY (SV *req) 453void DESTROY (SV *req)
454 ALIAS:
455 cancel = 1
250 CODE: 456 CODE:
251{ 457{
252 struct ctx *c; 458 struct ctx *c;
253 459
254 if (!(SvROK (req) && SvOBJECT (SvRV (req)) 460 if (!(SvROK (req) && SvOBJECT (SvRV (req))
258 c = (struct ctx *)SvPVX (SvRV (req)); 464 c = (struct ctx *)SvPVX (SvRV (req));
259 465
260 if (c->cb) 466 if (c->cb)
261 { 467 {
262 ev_unref (); 468 ev_unref ();
469 SvREFCNT_dec (c->cb);
470 c->cb = 0;
263 adns_cancel (c->query); 471 adns_cancel (c->query);
264 SvREFCNT_dec (c->cb); 472 SvREFCNT_dec (c->self);
265 } 473 }
266
267 SvREFCNT_dec (c->self);
268} 474}
269 475
270 476
271 477
272 478

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines