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.6 by root, Wed Sep 1 16:38:07 2010 UTC vs.
Revision 1.13 by root, Tue Jun 3 03:08:34 2014 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines