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