ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-ADNS/ADNS.xs
Revision: 1.4
Committed: Sat Dec 1 15:30:08 2007 UTC (16 years, 7 months ago) by root
Branch: MAIN
Changes since 1.3: +20 -10 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <poll.h>
6 #include <adns.h>
7
8 #include "EVAPI.h"
9
10 static HV *stash;
11 static adns_state ads;
12
13 struct ctx
14 {
15 SV *self;
16 adns_query query;
17 SV *cb;
18 };
19
20 static void
21 process ()
22 {
23 dSP;
24
25 for (;;)
26 {
27 adns_query q = 0;
28 adns_answer *a;
29 void *ctx;
30 SV *cb;
31 struct ctx *c;
32 int r = adns_check (ads, &q, &a, &ctx);
33
34 printf ("check %d\n", r);//D
35 if (r)
36 break;
37
38 c = (struct ctx *)ctx;
39 cb = c->cb;
40 c->cb = 0;
41 ev_unref ();
42
43 free (a);
44
45 PUSHMARK (SP);
46 printf ("call %s\n", SvPV_nolen(cb));
47 PUTBACK;
48 call_sv (cb, G_VOID | G_DISCARD);
49 SPAGAIN;
50
51 SvREFCNT_dec (cb);
52 SvREFCNT_dec (c->self);
53 }
54 }
55
56 static struct pollfd *fds;
57 static int nfd, mfd;
58 static ev_io *iow;
59 static ev_timer tw;
60 static ev_prepare prepare_ev;
61 static struct timeval tv_now;
62
63 static void
64 update_now (EV_P)
65 {
66 ev_tstamp t = ev_now ();
67
68 tv_now.tv_sec = (long)t;
69 tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6);
70 }
71
72 static void
73 timer_cb (EV_P_ ev_timer *w, int revents)
74 {
75 }
76
77 static void
78 io_cb (EV_P_ ev_io *w, int revents)
79 {
80 update_now (EV_A);
81
82 if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
83 if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
84 }
85
86 // create io watchers for each fd and a timer before blocking
87 static void
88 prepare_cb (EV_P_ ev_prepare *w, int revents)
89 {
90 int i;
91 int timeout = 3600000;
92
93 ev_timer_stop (EV_A_ &tw);
94
95 for (i = 0; i < nfd; ++i)
96 ev_io_stop (EV_A_ iow + i);
97
98 process ();
99
100 update_now (EV_A);
101
102 nfd = mfd;
103
104 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
105 {
106 mfd = nfd;
107
108 free (iow); iow = malloc (mfd * sizeof (struct pollfd));
109 free (fds); fds = malloc (mfd * sizeof (ev_io));
110 }
111
112 printf ("to %d\n", timeout);//d
113
114 ev_timer_set (&tw, timeout * 1e-3, 0.);
115 ev_timer_start (EV_A_ &tw);
116
117 // create one ev_io per pollfd
118 for (i = 0; i < nfd; ++i)
119 {
120 ev_io_init (iow + i, io_cb, fds [i].fd,
121 ((fds [i].events & POLLIN ? EV_READ : 0)
122 | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
123
124 ev_io_start (EV_A_ iow + i);
125 }
126 }
127
128 MODULE = EV::ADNS PACKAGE = EV::ADNS
129
130 PROTOTYPES: ENABLE
131
132 BOOT:
133 {
134 stash = gv_stashpv ("EV::ADNS", 1);
135
136 static const struct {
137 const char *name;
138 IV iv;
139 } *civ, const_iv[] = {
140 # define const_iv(name) { # name, (IV) adns_ ## name },
141 const_iv (if_none)
142 const_iv (if_noenv)
143 const_iv (if_noerrprint)
144 const_iv (if_noserverwarn)
145 const_iv (if_debug)
146 const_iv (if_logpid)
147 const_iv (if_noautosys)
148 const_iv (if_eintr)
149 const_iv (if_nosigpipe)
150 const_iv (if_checkc_entex)
151 const_iv (if_checkc_freq)
152
153 const_iv (qf_none)
154 const_iv (qf_search)
155 const_iv (qf_usevc)
156 const_iv (qf_owner)
157 const_iv (qf_quoteok_query)
158 const_iv (qf_quoteok_cname)
159 const_iv (qf_quoteok_anshost)
160 const_iv (qf_quotefail_cname)
161 const_iv (qf_cname_loose)
162 const_iv (qf_cname_forbid)
163
164 const_iv (rrt_typemask)
165 const_iv (_qtf_deref)
166 const_iv (_qtf_mail822)
167 const_iv (r_unknown)
168 const_iv (r_none)
169 const_iv (r_a)
170 const_iv (r_ns_raw)
171 const_iv (r_ns)
172 const_iv (r_cname)
173 const_iv (r_soa_raw)
174 const_iv (r_soa)
175 const_iv (r_ptr_raw)
176 const_iv (r_ptr)
177 const_iv (r_hinfo)
178 const_iv (r_mx_raw)
179 const_iv (r_mx)
180 const_iv (r_txt)
181 const_iv (r_rp_raw)
182 const_iv (r_rp)
183 const_iv (r_srv_raw)
184 const_iv (r_srv)
185 const_iv (r_addr)
186
187 const_iv (s_ok)
188 const_iv (s_nomemory)
189 const_iv (s_unknownrrtype)
190 const_iv (s_systemfail)
191 const_iv (s_max_localfail)
192 const_iv (s_timeout)
193 const_iv (s_allservfail)
194 const_iv (s_norecurse)
195 const_iv (s_invalidresponse)
196 const_iv (s_unknownformat)
197 const_iv (s_max_remotefail)
198 const_iv (s_rcodeservfail)
199 const_iv (s_rcodeformaterror)
200 const_iv (s_rcodenotimplemented)
201 const_iv (s_rcoderefused)
202 const_iv (s_rcodeunknown)
203 const_iv (s_max_tempfail)
204 const_iv (s_inconsistent)
205 const_iv (s_prohibitedcname)
206 const_iv (s_answerdomaininvalid)
207 const_iv (s_answerdomaintoolong)
208 const_iv (s_invaliddata)
209 const_iv (s_max_misconfig)
210 const_iv (s_querydomainwrong)
211 const_iv (s_querydomaininvalid)
212 const_iv (s_querydomaintoolong)
213 const_iv (s_max_misquery)
214 const_iv (s_nxdomain)
215 const_iv (s_nodata)
216 const_iv (s_max_permfail)
217 };
218
219 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
220 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
221
222 I_EV_API ("EV::ADNS");
223
224 ev_prepare_init (&prepare_ev, prepare_cb); ev_prepare_start (EV_DEFAULT_ &prepare_ev);
225 ev_unref ();
226
227 ev_init (&tw, timer_cb);
228
229 adns_init (&ads, adns_if_noenv | adns_if_noerrprint | adns_if_noserverwarn | adns_if_noautosys, 0);
230 }
231
232 void submit (char *owner, int type, int flags, SV *cb)
233 PPCODE:
234 {
235 SV *csv = NEWSV (0, sizeof (struct ctx));
236 struct ctx *c = (struct ctx *)SvPVX (csv);
237 int r = adns_submit (ads, owner, type, flags, (void *)c, &c->query);
238
239 if (r)
240 {
241 SvREFCNT_dec (csv);
242 XSRETURN_EMPTY;
243 }
244 else
245 {
246 ev_ref ();
247 SvPOK_only (csv);
248 SvCUR_set (csv, sizeof (struct ctx));
249 c->self = csv;
250 c->cb = newSVsv (cb);
251
252 if (GIMME_V != G_VOID)
253 {
254 csv = sv_2mortal (newRV_noinc (csv));
255 sv_bless (csv, stash);
256 XPUSHs (csv);
257 }
258 }
259 }
260
261 void DESTROY (SV *req)
262 CODE:
263 {
264 struct ctx *c;
265
266 if (!(SvROK (req) && SvOBJECT (SvRV (req))
267 && (SvSTASH (SvRV (req)) == stash)))
268 croak ("object is not of type EV::ADNS");
269
270 c = (struct ctx *)SvPVX (SvRV (req));
271
272 if (c->cb)
273 {
274 ev_unref ();
275 adns_cancel (c->query);
276 SvREFCNT_dec (c->cb);
277 }
278 }
279
280
281
282