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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines