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