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

# User Rev Content
1 root 1.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 root 1.2 static HV *stash;
11 root 1.1 static adns_state ads;
12    
13     struct ctx
14     {
15 root 1.2 SV *self;
16     adns_query query;
17 root 1.1 SV *cb;
18     };
19    
20     static void
21     process ()
22     {
23 root 1.3 dSP;
24    
25 root 1.1 for (;;)
26     {
27 root 1.4 adns_query q = 0;
28 root 1.1 adns_answer *a;
29 root 1.3 void *ctx;
30     SV *cb;
31     struct ctx *c;
32     int r = adns_check (ads, &q, &a, &ctx);
33 root 1.1
34 root 1.4 printf ("check %d\n", r);//D
35 root 1.1 if (r)
36     break;
37 root 1.3
38     c = (struct ctx *)ctx;
39     cb = c->cb;
40     c->cb = 0;
41     ev_unref ();
42    
43 root 1.5 PUSHMARK (SP);
44    
45     XPUSHs (sv_2mortal (newSViv (a->status)));
46 root 1.4 free (a);
47    
48     PUTBACK;
49 root 1.5 call_sv (cb, G_VOID | G_DISCARD | G_EVAL);
50 root 1.4 SPAGAIN;
51 root 1.3
52     SvREFCNT_dec (cb);
53 root 1.4 SvREFCNT_dec (c->self);
54 root 1.1 }
55     }
56    
57     static struct pollfd *fds;
58 root 1.4 static int nfd, mfd;
59 root 1.1 static ev_io *iow;
60     static ev_timer tw;
61     static ev_prepare prepare_ev;
62 root 1.2 static struct timeval tv_now;
63 root 1.1
64     static void
65     update_now (EV_P)
66     {
67 root 1.2 ev_tstamp t = ev_now ();
68 root 1.1
69 root 1.2 tv_now.tv_sec = (long)t;
70     tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6);
71 root 1.1 }
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 root 1.4 nfd = mfd;
104    
105 root 1.1 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
106     {
107 root 1.4 mfd = nfd;
108    
109     free (iow); iow = malloc (mfd * sizeof (struct pollfd));
110     free (fds); fds = malloc (mfd * sizeof (ev_io));
111 root 1.1 }
112    
113 root 1.4 printf ("to %d\n", timeout);//d
114    
115 root 1.1 ev_timer_set (&tw, timeout * 1e-3, 0.);
116     ev_timer_start (EV_A_ &tw);
117    
118 root 1.4 // create one ev_io per pollfd
119 root 1.1 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 root 1.2 stash = gv_stashpv ("EV::ADNS", 1);
136 root 1.1
137     static const struct {
138     const char *name;
139     IV iv;
140     } *civ, const_iv[] = {
141 root 1.3 # define const_iv(name) { # name, (IV) adns_ ## name },
142 root 1.1 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 root 1.3 void submit (char *owner, int type, int flags, SV *cb)
234 root 1.2 PPCODE:
235 root 1.1 {
236 root 1.2 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 root 1.1
240     if (r)
241     {
242 root 1.2 SvREFCNT_dec (csv);
243 root 1.1 XSRETURN_EMPTY;
244     }
245 root 1.2 else
246     {
247 root 1.3 ev_ref ();
248 root 1.2 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 root 1.5 csv = sv_2mortal (newRV_inc (csv));
256 root 1.2 sv_bless (csv, stash);
257     XPUSHs (csv);
258     }
259     }
260 root 1.1 }
261    
262 root 1.2 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 root 1.3 ev_unref ();
276 root 1.2 adns_cancel (c->query);
277     SvREFCNT_dec (c->cb);
278     }
279     }
280    
281    
282 root 1.1
283