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.7 by root, Sat Dec 1 21:01:32 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;
26 23
27 return newRV_noinc ((SV *)av); 24 return newRV_noinc ((SV *)av);
28} 25}
29 26
30static void 27static void
31process () 28process (adns_state ads)
32{ 29{
33 dSP; 30 dSP;
34 31
35 for (;;) 32 for (;;)
36 { 33 {
69 case adns_r_ptr_raw: 66 case adns_r_ptr_raw:
70 sv = newSVpv (a->rrs.str [i], 0); 67 sv = newSVpv (a->rrs.str [i], 0);
71 break; 68 break;
72 69
73 case adns_r_txt: 70 case adns_r_txt:
74 sv = newSVpvn (a->rrs.manyistr [i]->str, a->rrs.manyistr [i]->i); 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 }
75 break; 83 break;
76 84
77 case adns_r_a: 85 case adns_r_a:
78 sv = newSVpv (inet_ntoa (a->rrs.inaddr [i]), 0); 86 sv = newSVpv (inet_ntoa (a->rrs.inaddr [i]), 0);
79 break; 87 break;
84 92
85 case adns_r_hinfo: 93 case adns_r_hinfo:
86 { 94 {
87 /* untested */ 95 /* untested */
88 AV *av = newAV (); 96 AV *av = newAV ();
89 sv = newRV_noinc ((SV *)av);
90 adns_rr_intstrpair *rr = a->rrs.intstrpair + i; 97 adns_rr_intstrpair *rr = a->rrs.intstrpair + i;
91 98
92 av_push (av, newSVpvn (rr->array [0].str, rr->array [0].i)); 99 av_push (av, newSVpvn (rr->array [0].str, rr->array [0].i));
93 av_push (av, newSVpvn (rr->array [1].str, rr->array [1].i)); 100 av_push (av, newSVpvn (rr->array [1].str, rr->array [1].i));
101
102 sv = newRV_noinc ((SV *)av);
94 } 103 }
95 break; 104 break;
96 105
97 case adns_r_rp: 106 case adns_r_rp:
98 case adns_r_rp_raw: 107 case adns_r_rp_raw:
99 { 108 {
100 /* untested */ 109 /* untested */
101 AV *av = newAV (); 110 AV *av = newAV ();
102 sv = newRV_noinc ((SV *)av);
103 adns_rr_strpair *rr = a->rrs.strpair + i; 111 adns_rr_strpair *rr = a->rrs.strpair + i;
104 112
105 av_push (av, newSVpv (rr->array [0], 0)); 113 av_push (av, newSVpv (rr->array [0], 0));
106 av_push (av, newSVpv (rr->array [1], 0)); 114 av_push (av, newSVpv (rr->array [1], 0));
115
116 sv = newRV_noinc ((SV *)av);
107 } 117 }
108 break; 118 break;
109 119
110 case adns_r_mx: 120 case adns_r_mx:
111 { 121 {
112 AV *av = newAV (); 122 AV *av = newAV ();
113 sv = newRV_noinc ((SV *)av);
114 adns_rr_inthostaddr *rr = a->rrs.inthostaddr + i; 123 adns_rr_inthostaddr *rr = a->rrs.inthostaddr + i;
115 124
116 av_push (av, newSViv (rr->i)); 125 av_push (av, newSViv (rr->i));
117 av_push (av, ha2sv (&rr->ha)); 126 av_push (av, ha2sv (&rr->ha));
127
128 sv = newRV_noinc ((SV *)av);
118 } 129 }
119 break; 130 break;
120 131
121 case adns_r_mx_raw: 132 case adns_r_mx_raw:
122 { 133 {
123 AV *av = newAV (); 134 AV *av = newAV ();
124 sv = newRV_noinc ((SV *)av);
125 adns_rr_intstr *rr = a->rrs.intstr + i; 135 adns_rr_intstr *rr = a->rrs.intstr + i;
126 136
127 av_push (av, newSViv (rr->i)); 137 av_push (av, newSViv (rr->i));
128 av_push (av, newSVpv (rr->str, 0)); 138 av_push (av, newSVpv (rr->str, 0));
139
140 sv = newRV_noinc ((SV *)av);
129 } 141 }
130 break; 142 break;
131 143
132 case adns_r_soa: 144 case adns_r_soa:
133 case adns_r_soa_raw: 145 case adns_r_soa_raw:
134 { 146 {
135 AV *av = newAV (); 147 AV *av = newAV ();
136 sv = newRV_noinc ((SV *)av);
137 adns_rr_soa *rr = a->rrs.soa + i; 148 adns_rr_soa *rr = a->rrs.soa + i;
138 149
139 av_push (av, newSVpv (rr->mname, 0)); 150 av_push (av, newSVpv (rr->mname, 0));
140 av_push (av, newSVpv (rr->rname, 0)); 151 av_push (av, newSVpv (rr->rname, 0));
141 av_push (av, newSVuv (rr->serial)); 152 av_push (av, newSVuv (rr->serial));
142 av_push (av, newSVuv (rr->refresh)); 153 av_push (av, newSVuv (rr->refresh));
143 av_push (av, newSVuv (rr->retry)); 154 av_push (av, newSVuv (rr->retry));
144 av_push (av, newSVuv (rr->expire)); 155 av_push (av, newSVuv (rr->expire));
145 av_push (av, newSVuv (rr->minimum)); 156 av_push (av, newSVuv (rr->minimum));
157
158 sv = newRV_noinc ((SV *)av);
146 } 159 }
147 break; 160 break;
148 161
149 case adns_r_srv_raw: 162 case adns_r_srv_raw:
150 { 163 {
151 AV *av = newAV (); 164 AV *av = newAV ();
152 sv = newRV_noinc ((SV *)av);
153 adns_rr_srvraw *rr = a->rrs.srvraw + i; 165 adns_rr_srvraw *rr = a->rrs.srvraw + i;
154 166
155 av_push (av, newSViv (rr->priority)); 167 av_push (av, newSViv (rr->priority));
156 av_push (av, newSViv (rr->weight)); 168 av_push (av, newSViv (rr->weight));
157 av_push (av, newSViv (rr->port)); 169 av_push (av, newSViv (rr->port));
158 av_push (av, newSVpv (rr->host, 0)); 170 av_push (av, newSVpv (rr->host, 0));
171
172 sv = newRV_noinc ((SV *)av);
159 } 173 }
160 break; 174 break;
161 175
162 case adns_r_srv: 176 case adns_r_srv:
163 { 177 {
164 AV *av = newAV (); 178 AV *av = newAV ();
165 sv = newRV_noinc ((SV *)av);
166 adns_rr_srvha *rr = a->rrs.srvha + i; 179 adns_rr_srvha *rr = a->rrs.srvha + i;
167 180
168 av_push (av, newSViv (rr->priority)); 181 av_push (av, newSViv (rr->priority));
169 av_push (av, newSViv (rr->weight)); 182 av_push (av, newSViv (rr->weight));
170 av_push (av, newSViv (rr->port)); 183 av_push (av, newSViv (rr->port));
171 av_push (av, ha2sv (&rr->ha)); 184 av_push (av, ha2sv (&rr->ha));
185
186 sv = newRV_noinc ((SV *)av);
172 } 187 }
173 break; 188 break;
174 189
175 case adns_r_unknown: 190 case adns_r_unknown:
176 sv = newSVpvn (a->rrs.byteblock [i].data, a->rrs.byteblock [i].len); 191 sv = newSVpvn (a->rrs.byteblock [i].data, a->rrs.byteblock [i].len);
197 212
198static struct pollfd *fds; 213static struct pollfd *fds;
199static int nfd, mfd; 214static int nfd, mfd;
200static ev_io *iow; 215static ev_io *iow;
201static ev_timer tw; 216static ev_timer tw;
217static ev_idle iw;
202static ev_prepare prepare_ev; 218static ev_prepare pw;
203static struct timeval tv_now; 219static struct timeval tv_now;
204 220
205static void 221static void
206update_now (EV_P) 222update_now (EV_P)
207{ 223{
208 ev_tstamp t = ev_now (); 224 ev_tstamp t = ev_now ();
209 225
210 tv_now.tv_sec = (long)t; 226 tv_now.tv_sec = (long)t;
211 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);
212} 234}
213 235
214static void 236static void
215timer_cb (EV_P_ ev_timer *w, int revents) 237timer_cb (EV_P_ ev_timer *w, int revents)
216{ 238{
239 adns_state ads = (adns_state)w->data;
240 update_now ();
241
242 adns_processtimeouts (ads, &tv_now);
217} 243}
218 244
219static void 245static void
220io_cb (EV_P_ ev_io *w, int revents) 246io_cb (EV_P_ ev_io *w, int revents)
221{ 247{
248 adns_state ads = (adns_state)w->data;
222 update_now (EV_A); 249 update_now (EV_A);
223 250
224 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now); 251 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
225 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now); 252 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
226} 253}
229static void 256static void
230prepare_cb (EV_P_ ev_prepare *w, int revents) 257prepare_cb (EV_P_ ev_prepare *w, int revents)
231{ 258{
232 int i; 259 int i;
233 int timeout = 3600000; 260 int timeout = 3600000;
261 adns_state ads = (adns_state)w->data;
234 262
235 if (ev_is_active (&tw)) 263 if (ev_is_active (&tw))
236 { 264 {
237 ev_ref (); 265 ev_ref ();
238 ev_timer_stop (EV_A_ &tw); 266 ev_timer_stop (EV_A_ &tw);
239 } 267 }
240 268
269 if (ev_is_active (&iw))
270 ev_idle_stop (EV_A_ &iw);
271
241 for (i = 0; i < nfd; ++i) 272 for (i = 0; i < nfd; ++i)
242 { 273 {
243 ev_ref (); 274 ev_ref ();
244 ev_io_stop (EV_A_ iow + i); 275 ev_io_stop (EV_A_ iow + i);
245 } 276 }
246 277
247 process (); 278 process (ads);
248
249 update_now (EV_A); 279 update_now (EV_A);
250 280
251 nfd = mfd; 281 nfd = mfd;
252 282
253 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now)) 283 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
271 301
272 ev_io_start (EV_A_ iow + i); 302 ev_io_start (EV_A_ iow + i);
273 ev_unref (); 303 ev_unref ();
274 } 304 }
275} 305}
306
307static HV *stash;
308static adns_state ads;
276 309
277MODULE = EV::ADNS PACKAGE = EV::ADNS 310MODULE = EV::ADNS PACKAGE = EV::ADNS
278 311
279PROTOTYPES: ENABLE 312PROTOTYPES: ENABLE
280 313
368 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; )
369 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 402 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
370 403
371 I_EV_API ("EV::ADNS"); 404 I_EV_API ("EV::ADNS");
372 405
373 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);
374 ev_unref (); 411 ev_unref ();
375 412
413 ev_init (&iw, idle_cb); ev_set_priority (&iw, EV_MINPRI);
414 iw.data = (void *)ads;
376 ev_init (&tw, timer_cb); 415 ev_init (&tw, timer_cb);
377 416 tw.data = (void *)ads;
378 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
379} 417}
380 418
381void submit (char *owner, int type, int flags, SV *cb) 419void submit (char *owner, int type, int flags, SV *cb)
382 PPCODE: 420 PPCODE:
383{ 421{
398 SvCUR_set (csv, sizeof (struct ctx)); 436 SvCUR_set (csv, sizeof (struct ctx));
399 437
400 c->self = csv; 438 c->self = csv;
401 c->cb = newSVsv (cb); 439 c->cb = newSVsv (cb);
402 440
441 if (!ev_is_active (&iw))
442 ev_idle_start (EV_A_ &iw);
443
403 if (GIMME_V != G_VOID) 444 if (GIMME_V != G_VOID)
404 { 445 {
405 csv = sv_2mortal (newRV_inc (csv)); 446 csv = sv_2mortal (newRV_inc (csv));
406 sv_bless (csv, stash); 447 sv_bless (csv, stash);
407 XPUSHs (csv); 448 XPUSHs (csv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines