ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro-Mysql/Mysql.xs
(Generate patch)

Comparing Coro-Mysql/Mysql.xs (file contents):
Revision 1.2 by root, Tue Jun 16 17:28:00 2009 UTC vs.
Revision 1.10 by root, Fri Aug 2 04:08:56 2013 UTC

6 6
7#include "EXTERN.h" 7#include "EXTERN.h"
8#include "perl.h" 8#include "perl.h"
9#include "XSUB.h" 9#include "XSUB.h"
10 10
11#if HAVE_EV
12# include "EVAPI.h"
13# include "CoroAPI.h"
14#endif
15
16#define IN_DESTRUCT PL_dirty
17
11typedef U16 uint16; 18typedef U16 uint16;
12 19
13/* cached function gv's */ 20/* cached function gv's */
14static CV *readable, *writable; 21static CV *readable, *writable;
22static int use_ev;
15 23
16#include "violite.h" 24#include "violite.h"
17 25
18#define DESC_OFFSET 22
19
20#define CoMy_MAGIC 0x436f4d79 26#define CoMy_MAGIC 0x436f4d79
21 27
22typedef struct { 28typedef struct {
29#if DESC_IS_PTR
30 char desc[30];
31 const char *old_desc;
32#endif
23 int magic; 33 int magic;
24 SV *corosocket; 34 SV *corohandle_sv, *corohandle;
25 int bufofs, bufcnt; 35 int bufofs, bufcnt;
36#if HAVE_EV
37 ev_io rw, ww;
38#endif
26 char buf[VIO_READ_BUFFER_SIZE]; 39 char buf[VIO_READ_BUFFER_SIZE];
27} ourdata; 40} ourdata;
28 41
42#if DESC_IS_PTR
43# define OURDATAPTR (*(ourdata **)&((vio)->desc))
44#else
45# define DESC_OFFSET 22
29#define OURDATAPTR (*((ourdata **)((vio)->desc + DESC_OFFSET))) 46# define OURDATAPTR (*((ourdata **)((vio)->desc + DESC_OFFSET)))
47#endif
30 48
31static int 49static xlen
32our_read (Vio *vio, gptr p, int len) 50our_read (Vio *vio, xgptr p, xlen len)
33{ 51{
34 ourdata *our = OURDATAPTR; 52 ourdata *our = OURDATAPTR;
35 53
36 if (!our->bufcnt) 54 if (!our->bufcnt)
37 { 55 {
45 rd = recv (vio->sd, our->buf, sizeof (our->buf), 0); 63 rd = recv (vio->sd, our->buf, sizeof (our->buf), 0);
46 64
47 if (rd >= 0 || errno != EAGAIN) 65 if (rd >= 0 || errno != EAGAIN)
48 break; 66 break;
49 67
68#if HAVE_EV
69 if (use_ev)
50 { 70 {
71 our->rw.data = (void *)sv_2mortal (SvREFCNT_inc (CORO_CURRENT));
72 ev_io_start (EV_DEFAULT_UC, &(our->rw));
73 CORO_SCHEDULE;
74 ev_io_stop (EV_DEFAULT_UC, &(our->rw)); /* avoids races */
75 }
76 else
77#endif
78 {
51 dSP; 79 dSP;
52 PUSHMARK (SP); 80 PUSHMARK (SP);
53 XPUSHs (our->corosocket); 81 XPUSHs (our->corohandle);
54 PUTBACK; 82 PUTBACK;
55 call_sv ((SV *)readable, G_VOID | G_DISCARD); 83 call_sv ((SV *)readable, G_VOID | G_DISCARD);
56 } 84 }
57 } 85 }
58 86
59 if (rd <= 0) 87 if (rd <= 0)
60 return rd; 88 return rd;
61 89
71 our->bufcnt -= len; 99 our->bufcnt -= len;
72 100
73 return len; 101 return len;
74} 102}
75 103
76static int 104static xlen
77our_write (Vio *vio, const gptr p, int len) 105our_write (Vio *vio, cxgptr p, xlen len)
78{ 106{
79 char *ptr = (char *)p; 107 char *ptr = (char *)p;
80 my_bool dummy; 108 my_bool dummy;
81 109
82 vio->vioblocking (vio, 0, &dummy); 110 vio->vioblocking (vio, 0, &dummy);
90 ptr += wr; 118 ptr += wr;
91 len -= wr; 119 len -= wr;
92 } 120 }
93 else if (errno == EAGAIN) 121 else if (errno == EAGAIN)
94 { 122 {
123 ourdata *our = OURDATAPTR;
124
125#if HAVE_EV
126 if (use_ev)
127 {
128 our->ww.data = (void *)sv_2mortal (SvREFCNT_inc (CORO_CURRENT));
129 ev_io_start (EV_DEFAULT_UC, &(our->ww));
130 CORO_SCHEDULE;
131 ev_io_stop (EV_DEFAULT_UC, &(our->ww)); /* avoids races */
132 }
133 else
134#endif
135 {
95 dSP; 136 dSP;
96 PUSHMARK (SP); 137 PUSHMARK (SP);
97 XPUSHs (OURDATAPTR->corosocket); 138 XPUSHs (our->corohandle);
98 PUTBACK; 139 PUTBACK;
99 call_sv ((SV *)writable, G_VOID | G_DISCARD); 140 call_sv ((SV *)writable, G_VOID | G_DISCARD);
141 }
100 } 142 }
101 else if (ptr == (char *)p) 143 else if (ptr == (char *)p)
102 return -1; 144 return -1;
103 else 145 else
104 break; 146 break;
105 } 147 }
106 148
107 return ptr - (char *)p; 149 return ptr - (char *)p;
108} 150}
109 151
152static int
153our_close (Vio *vio)
154{
155 ourdata *our = OURDATAPTR;
156
157 if (vio->read != our_read)
158 croak ("vio.read has unexpected content during unpatch - wtf?");
159
160 if (vio->write != our_write)
161 croak ("vio.write has unexpected content during unpatch - wtf?");
162
163 if (vio->vioclose != our_close)
164 croak ("vio.vioclose has unexpected content during unpatch - wtf?");
165
166#if HAVE_EV
167 if (use_ev)
168 {
169 ev_io_stop (EV_DEFAULT_UC, &(our->rw));
170 ev_io_stop (EV_DEFAULT_UC, &(our->ww));
171 }
172#endif
173
174 SvREFCNT_dec (our->corohandle);
175 SvREFCNT_dec (our->corohandle_sv);
176
177#if DESC_IS_PTR
178 vio->desc = our->old_desc;
179#endif
180
181 Safefree (our);
182
183 vio->read = vio_read;
184 vio->write = vio_write;
185 vio->vioclose = vio_close;
186
187 vio->vioclose (vio);
188}
189
190#if HAVE_EV
191static void
192iocb (EV_P_ ev_io *w, int revents)
193{
194 ev_io_stop (EV_A, w);
195 CORO_READY ((SV *)w->data);
196}
197#endif
198
110MODULE = Coro::Mysql PACKAGE = Coro::Mysql 199MODULE = Coro::Mysql PACKAGE = Coro::Mysql
111 200
112BOOT: 201BOOT:
113{ 202{
114 readable = get_cv ("Coro::Mysql::readable", 0); 203 readable = get_cv ("Coro::Mysql::readable", 0);
116} 205}
117 206
118PROTOTYPES: ENABLE 207PROTOTYPES: ENABLE
119 208
120void 209void
121_patch (IV sock, int fd, SV *corosocket) 210_use_ev ()
211 PPCODE:
212{
213 static int onceonly;
214
215 if (!onceonly)
216 {
217 onceonly = 1;
218#if HAVE_EV
219 I_EV_API ("Coro::Mysql");
220 I_CORO_API ("Coro::Mysql");
221 use_ev = 1;
222#endif
223 }
224
225 XPUSHs (use_ev ? &PL_sv_yes : &PL_sv_no);
226}
227
228void
229_patch (IV sock, int fd, unsigned long client_version, SV *corohandle_sv, SV *corohandle)
122 CODE: 230 CODE:
123{ 231{
124 MYSQL *my = (MYSQL *)sock; 232 MYSQL *my = (MYSQL *)sock;
125 Vio *vio = my->net.vio; 233 Vio *vio = my->net.vio;
126 ourdata *our; 234 ourdata *our;
127 235
236 /* matching versions are required but not sufficient */
237 if (client_version != mysql_get_client_version ())
238 croak ("DBD::mysql linked against different libmysqlclient library than Coro::Mysql (%lu vs. %lu).",
239 client_version, mysql_get_client_version ());
240
128 if (fd != my->net.fd) 241 if (fd != my->net.fd)
129 croak ("DBD::mysql fd and libmysql disagree - library mismatch, unsupported transport or API changes?"); 242 croak ("DBD::mysql fd and libmysql disagree - library mismatch, unsupported transport or API changes?");
130 243
131 if (fd != vio->sd) 244 if (fd != vio->sd)
132 croak ("DBD::mysql fd and vio-sd disagree - library mismatch, unsupported transport or API changes?"); 245 croak ("DBD::mysql fd and vio-sd disagree - library mismatch, unsupported transport or API changes?");
133 246
247 if (vio->vioclose != vio_close)
248 croak ("vio.vioclose has unexpected content - library mismatch, unsupported transport or API changes?");
249
134 if (vio->write != vio_write) 250 if (vio->write != vio_write)
135 croak ("vio.write has unexpected content - library mismatch, unsupported transport or API changes?"); 251 croak ("vio.write has unexpected content - library mismatch, unsupported transport or API changes?");
136 252
137 if (vio->read != vio_read && vio->read != vio_read_buff) 253 if (vio->read != vio_read
254 && vio->read != vio_read_buff)
138 croak ("vio.read has unexpected content - library mismatch, unsupported transport or API changes?"); 255 croak ("vio.read has unexpected content - library mismatch, unsupported transport or API changes?");
139 256
140 Newz (0, our, 1, ourdata); 257 Newz (0, our, 1, ourdata);
141 our->magic = CoMy_MAGIC; 258 our->magic = CoMy_MAGIC;
259 our->corohandle_sv = newSVsv (corohandle_sv);
142 our->corosocket = newSVsv (corosocket); 260 our->corohandle = newSVsv (corohandle);
143 261#if HAVE_EV
262 if (use_ev)
263 {
264 ev_io_init (&(our->rw), iocb, vio->sd, EV_READ);
265 ev_io_init (&(our->ww), iocb, vio->sd, EV_WRITE);
266 }
267#endif
268#if DESC_IS_PTR
269 our->old_desc = vio->desc;
270 strncpy (our->desc, vio->desc, sizeof (our->desc));
271 our->desc [sizeof (our->desc) - 1] = 0;
272#else
144 vio->desc [DESC_OFFSET - 1] = 0; 273 vio->desc [DESC_OFFSET - 1] = 0;
274#endif
145 OURDATAPTR = our; 275 OURDATAPTR = our;
146 276
277 vio->vioclose = our_close;
147 vio->write = our_write; 278 vio->write = our_write;
148 vio->read = our_read; 279 vio->read = our_read;
149} 280}
150 281
151void
152_unpatch (IV sock)
153 CODE:
154{
155 MYSQL *my = (MYSQL *)sock;
156 Vio *vio = my->net.vio;
157 my_bool dummy;
158
159 if (vio->read != our_read)
160 croak ("vio.read has unexpected content during unpatch - wtf?");
161
162 if (vio->write != our_write)
163 croak ("vio.write has unexpected content during unpatch - wtf?");
164
165 SvREFCNT_dec (OURDATAPTR->corosocket);
166
167 Safefree (OURDATAPTR);
168
169 vio->read = vio_read;
170 vio->write = vio_write;
171}
172
173
174

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines