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, 8 months ago) by root
Branch: MAIN
Changes since 1.3: +20 -10 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.4 free (a);
44    
45 root 1.3 PUSHMARK (SP);
46 root 1.4 printf ("call %s\n", SvPV_nolen(cb));
47     PUTBACK;
48     call_sv (cb, G_VOID | G_DISCARD);
49     SPAGAIN;
50 root 1.3
51     SvREFCNT_dec (cb);
52 root 1.4 SvREFCNT_dec (c->self);
53 root 1.1 }
54     }
55    
56     static struct pollfd *fds;
57 root 1.4 static int nfd, mfd;
58 root 1.1 static ev_io *iow;
59     static ev_timer tw;
60     static ev_prepare prepare_ev;
61 root 1.2 static struct timeval tv_now;
62 root 1.1
63     static void
64     update_now (EV_P)
65     {
66 root 1.2 ev_tstamp t = ev_now ();
67 root 1.1
68 root 1.2 tv_now.tv_sec = (long)t;
69     tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6);
70 root 1.1 }
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 root 1.4 nfd = mfd;
103    
104 root 1.1 while (adns_beforepoll (ads, fds, &nfd, &timeout, &tv_now))
105     {
106 root 1.4 mfd = nfd;
107    
108     free (iow); iow = malloc (mfd * sizeof (struct pollfd));
109     free (fds); fds = malloc (mfd * sizeof (ev_io));
110 root 1.1 }
111    
112 root 1.4 printf ("to %d\n", timeout);//d
113    
114 root 1.1 ev_timer_set (&tw, timeout * 1e-3, 0.);
115     ev_timer_start (EV_A_ &tw);
116    
117 root 1.4 // create one ev_io per pollfd
118 root 1.1 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 root 1.2 stash = gv_stashpv ("EV::ADNS", 1);
135 root 1.1
136     static const struct {
137     const char *name;
138     IV iv;
139     } *civ, const_iv[] = {
140 root 1.3 # define const_iv(name) { # name, (IV) adns_ ## name },
141 root 1.1 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 root 1.3 void submit (char *owner, int type, int flags, SV *cb)
233 root 1.2 PPCODE:
234 root 1.1 {
235 root 1.2 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 root 1.1
239     if (r)
240     {
241 root 1.2 SvREFCNT_dec (csv);
242 root 1.1 XSRETURN_EMPTY;
243     }
244 root 1.2 else
245     {
246 root 1.3 ev_ref ();
247 root 1.2 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 root 1.4 csv = sv_2mortal (newRV_noinc (csv));
255 root 1.2 sv_bless (csv, stash);
256     XPUSHs (csv);
257     }
258     }
259 root 1.1 }
260    
261 root 1.2 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 root 1.3 ev_unref ();
275 root 1.2 adns_cancel (c->query);
276     SvREFCNT_dec (c->cb);
277     }
278     }
279    
280    
281 root 1.1
282