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