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.5 by root, Sat Dec 1 15:54:40 2007 UTC vs.
Revision 1.10 by root, Mon Dec 3 19:04:54 2007 UTC

15 SV *self; 15 SV *self;
16 adns_query query; 16 adns_query query;
17 SV *cb; 17 SV *cb;
18}; 18};
19 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
20static void 30static void
21process () 31process ()
22{ 32{
23 dSP; 33 dSP;
24 34
25 for (;;) 35 for (;;)
26 { 36 {
37 int i;
27 adns_query q = 0; 38 adns_query q = 0;
28 adns_answer *a; 39 adns_answer *a;
29 void *ctx; 40 void *ctx;
30 SV *cb; 41 SV *cb;
31 struct ctx *c; 42 struct ctx *c;
32 int r = adns_check (ads, &q, &a, &ctx); 43 int r = adns_check (ads, &q, &a, &ctx);
33 44
34 printf ("check %d\n", r);//D
35 if (r) 45 if (r)
36 break; 46 break;
37 47
38 c = (struct ctx *)ctx; 48 c = (struct ctx *)ctx;
39 cb = c->cb; 49 cb = c->cb;
40 c->cb = 0; 50 c->cb = 0;
41 ev_unref (); 51 ev_unref ();
52 SvREFCNT_dec (c->self);
42 53
43 PUSHMARK (SP); 54 PUSHMARK (SP);
44 55
56 EXTEND (SP, a->nrrs + 2);
45 XPUSHs (sv_2mortal (newSViv (a->status))); 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
46 free (a); 206 free (a);
47 207
48 PUTBACK; 208 PUTBACK;
49 call_sv (cb, G_VOID | G_DISCARD | G_EVAL); 209 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
50 SPAGAIN; 210 SPAGAIN;
51 211
52 SvREFCNT_dec (cb); 212 SvREFCNT_dec (cb);
53 SvREFCNT_dec (c->self);
54 } 213 }
55} 214}
56 215
57static struct pollfd *fds; 216static struct pollfd *fds;
58static int nfd, mfd; 217static int nfd, mfd;
59static ev_io *iow; 218static ev_io *iow;
60static ev_timer tw; 219static ev_timer tw;
220static ev_idle iw;
61static ev_prepare prepare_ev; 221static ev_prepare prepare_ev;
62static struct timeval tv_now; 222static struct timeval tv_now;
63 223
64static void 224static void
65update_now (EV_P) 225update_now (EV_P)
66{ 226{
67 ev_tstamp t = ev_now (); 227 ev_tstamp t = ev_now ();
68 228
69 tv_now.tv_sec = (long)t; 229 tv_now.tv_sec = (long)t;
70 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6); 230 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e6);
231}
232
233static void
234idle_cb (EV_P_ ev_idle *w, int revents)
235{
236 ev_idle_stop (EV_A_ w);
71} 237}
72 238
73static void 239static void
74timer_cb (EV_P_ ev_timer *w, int revents) 240timer_cb (EV_P_ ev_timer *w, int revents)
75{ 241{
242 update_now ();
243
244 adns_processtimeouts (ads, &tv_now);
76} 245}
77 246
78static void 247static void
79io_cb (EV_P_ ev_io *w, int revents) 248io_cb (EV_P_ ev_io *w, int revents)
80{ 249{
89prepare_cb (EV_P_ ev_prepare *w, int revents) 258prepare_cb (EV_P_ ev_prepare *w, int revents)
90{ 259{
91 int i; 260 int i;
92 int timeout = 3600000; 261 int timeout = 3600000;
93 262
263 if (ev_is_active (&tw))
264 {
265 ev_ref ();
94 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);
95 271
96 for (i = 0; i < nfd; ++i) 272 for (i = 0; i < nfd; ++i)
273 {
274 ev_ref ();
97 ev_io_stop (EV_A_ iow + i); 275 ev_io_stop (EV_A_ iow + i);
276 }
98 277
99 process (); 278 process ();
100 279
101 update_now (EV_A); 280 update_now (EV_A);
102 281
104 283
105 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now)) 284 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
106 { 285 {
107 mfd = nfd; 286 mfd = nfd;
108 287
288 free (iow); iow = malloc (mfd * sizeof (ev_io));
109 free (iow); iow = malloc (mfd * sizeof (struct pollfd)); 289 free (fds); fds = malloc (mfd * sizeof (struct pollfd));
110 free (fds); fds = malloc (mfd * sizeof (ev_io));
111 } 290 }
112
113 printf ("to %d\n", timeout);//d
114 291
115 ev_timer_set (&tw, timeout * 1e-3, 0.); 292 ev_timer_set (&tw, timeout * 1e-3, 0.);
116 ev_timer_start (EV_A_ &tw); 293 ev_timer_start (EV_A_ &tw);
294 ev_unref ();
117 295
118 // create one ev_io per pollfd 296 // create one ev_io per pollfd
119 for (i = 0; i < nfd; ++i) 297 for (i = 0; i < nfd; ++i)
120 { 298 {
121 ev_io_init (iow + i, io_cb, fds [i].fd, 299 ev_io_init (iow + i, io_cb, fds [i].fd,
122 ((fds [i].events & POLLIN ? EV_READ : 0) 300 ((fds [i].events & POLLIN ? EV_READ : 0)
123 | (fds [i].events & POLLOUT ? EV_WRITE : 0))); 301 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
124 302
125 ev_io_start (EV_A_ iow + i); 303 ev_io_start (EV_A_ iow + i);
304 ev_unref ();
126 } 305 }
127} 306}
128 307
129MODULE = EV::ADNS PACKAGE = EV::ADNS 308MODULE = EV::ADNS PACKAGE = EV::ADNS
130 309
220 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 399 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
221 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 400 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
222 401
223 I_EV_API ("EV::ADNS"); 402 I_EV_API ("EV::ADNS");
224 403
225 ev_prepare_init (&prepare_ev, prepare_cb); ev_prepare_start (EV_DEFAULT_ &prepare_ev); 404 ev_prepare_init (&prepare_ev, prepare_cb);
405 ev_prepare_start (EV_DEFAULT_ &prepare_ev);
226 ev_unref (); 406 ev_unref ();
227 407
408 ev_init (&iw, idle_cb);
228 ev_init (&tw, timer_cb); 409 ev_init (&tw, timer_cb);
229 410
230 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0); 411 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
231} 412}
232 413
238 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query); 419 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query);
239 420
240 if (r) 421 if (r)
241 { 422 {
242 SvREFCNT_dec (csv); 423 SvREFCNT_dec (csv);
424 errno = r;
243 XSRETURN_EMPTY; 425 XSRETURN_EMPTY;
244 } 426 }
245 else 427 else
246 { 428 {
247 ev_ref (); 429 ev_ref ();
248 SvPOK_only (csv); 430 SvPOK_only (csv);
249 SvCUR_set (csv, sizeof (struct ctx)); 431 SvCUR_set (csv, sizeof (struct ctx));
432
250 c->self = csv; 433 c->self = csv;
251 c->cb = newSVsv (cb); 434 c->cb = newSVsv (cb);
435
436 if (!ev_is_active (&iw))
437 ev_idle_start (EV_A_ &iw);
252 438
253 if (GIMME_V != G_VOID) 439 if (GIMME_V != G_VOID)
254 { 440 {
255 csv = sv_2mortal (newRV_inc (csv)); 441 csv = sv_2mortal (newRV_inc (csv));
256 sv_bless (csv, stash); 442 sv_bless (csv, stash);
258 } 444 }
259 } 445 }
260} 446}
261 447
262void DESTROY (SV *req) 448void DESTROY (SV *req)
449 ALIAS:
450 cancel = 1
263 CODE: 451 CODE:
264{ 452{
265 struct ctx *c; 453 struct ctx *c;
266 454
267 if (!(SvROK (req) && SvOBJECT (SvRV (req)) 455 if (!(SvROK (req) && SvOBJECT (SvRV (req))
271 c = (struct ctx *)SvPVX (SvRV (req)); 459 c = (struct ctx *)SvPVX (SvRV (req));
272 460
273 if (c->cb) 461 if (c->cb)
274 { 462 {
275 ev_unref (); 463 ev_unref ();
464 SvREFCNT_dec (c->cb);
465 c->cb = 0;
276 adns_cancel (c->query); 466 adns_cancel (c->query);
277 SvREFCNT_dec (c->cb); 467 SvREFCNT_dec (c->self);
278 } 468 }
279} 469}
280 470
281 471
282 472

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines