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

# 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     adns_query q;
28     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     if (r)
35     break;
36 root 1.3
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 root 1.1 }
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 root 1.2 static struct timeval tv_now;
55 root 1.1
56     static void
57     update_now (EV_P)
58     {
59 root 1.2 ev_tstamp t = ev_now ();
60 root 1.1
61 root 1.2 tv_now.tv_sec = (long)t;
62     tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6);
63 root 1.1 }
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 root 1.2 stash = gv_stashpv ("EV::ADNS", 1);
122 root 1.1
123     static const struct {
124     const char *name;
125     IV iv;
126     } *civ, const_iv[] = {
127 root 1.3 # define const_iv(name) { # name, (IV) adns_ ## name },
128 root 1.1 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 root 1.3 void submit (char *owner, int type, int flags, SV *cb)
220 root 1.2 PPCODE:
221 root 1.1 {
222 root 1.2 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 root 1.1
226     if (r)
227     {
228 root 1.3 printf ("errn %d\n", r);//D
229 root 1.2 SvREFCNT_dec (csv);
230 root 1.1 XSRETURN_EMPTY;
231     }
232 root 1.2 else
233     {
234 root 1.3 ev_ref ();
235 root 1.2 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 root 1.1 }
248    
249 root 1.2 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 root 1.3 ev_unref ();
263 root 1.2 adns_cancel (c->query);
264     SvREFCNT_dec (c->cb);
265     }
266    
267     SvREFCNT_dec (c->self);
268     }
269    
270    
271 root 1.1
272