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 (16 years, 7 months ago) by root
Branch: MAIN
Changes since 1.1: +49 -12 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     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 root 1.2 static struct timeval tv_now;
41 root 1.1
42     static void
43     update_now (EV_P)
44     {
45 root 1.2 ev_tstamp t = ev_now ();
46 root 1.1
47 root 1.2 tv_now.tv_sec = (long)t;
48     tv_now.tv_usec = (long)((t - (ev_tstamp)tv_now.tv_sec) * 1e-6);
49 root 1.1 }
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 root 1.2 stash = gv_stashpv ("EV::ADNS", 1);
108 root 1.1 #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 root 1.2 void adns_submit (char *owner, int type, int flags, SV *cb)
208     PPCODE:
209 root 1.1 {
210 root 1.2 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 root 1.1
214     if (r)
215     {
216 root 1.2 SvREFCNT_dec (csv);
217 root 1.1 XSRETURN_EMPTY;
218     }
219 root 1.2 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 root 1.1 }
234    
235 root 1.2 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 root 1.1
257