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