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

Comparing EV-ADNS/ADNS.xs (file contents):
Revision 1.1 by root, Sat Dec 1 13:53:11 2007 UTC vs.
Revision 1.8 by root, Sat Dec 1 21:29:08 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines