ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro-Mysql/Mysql.xs
Revision: 1.5
Committed: Sat Jul 18 05:58:27 2009 UTC (14 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-1_01
Changes since 1.4: +38 -35 lines
Log Message:
riddify us of meta.yml garbage in manifest

File Contents

# Content
1 #include <sys/errno.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4
5 #include <mysql.h>
6
7 #include "EXTERN.h"
8 #include "perl.h"
9 #include "XSUB.h"
10
11 #define IN_DESTRUCT PL_dirty
12
13 typedef U16 uint16;
14
15 /* cached function gv's */
16 static CV *readable, *writable;
17
18 #include "violite.h"
19
20 #define DESC_OFFSET 22
21
22 #define CoMy_MAGIC 0x436f4d79
23
24 typedef struct {
25 int magic;
26 SV *corohandle_sv, *corohandle;
27 int bufofs, bufcnt;
28 char buf[VIO_READ_BUFFER_SIZE];
29 } ourdata;
30
31 #define OURDATAPTR (*((ourdata **)((vio)->desc + DESC_OFFSET)))
32
33 static int
34 our_read (Vio *vio, gptr p, int len)
35 {
36 ourdata *our = OURDATAPTR;
37
38 if (!our->bufcnt)
39 {
40 int rd;
41 my_bool dummy;
42
43 vio->vioblocking (vio, 0, &dummy);
44
45 for (;;)
46 {
47 rd = recv (vio->sd, our->buf, sizeof (our->buf), 0);
48
49 if (rd >= 0 || errno != EAGAIN)
50 break;
51
52 {
53 dSP;
54 PUSHMARK (SP);
55 XPUSHs (our->corohandle);
56 PUTBACK;
57 call_sv ((SV *)readable, G_VOID | G_DISCARD);
58 }
59 }
60
61 if (rd <= 0)
62 return rd;
63
64 our->bufcnt = rd;
65 our->bufofs = 0;
66 }
67
68 if (our->bufcnt < len)
69 len = our->bufcnt;
70
71 memcpy (p, our->buf + our->bufofs, len);
72 our->bufofs += len;
73 our->bufcnt -= len;
74
75 return len;
76 }
77
78 static int
79 our_write (Vio *vio, const gptr p, int len)
80 {
81 char *ptr = (char *)p;
82 my_bool dummy;
83
84 vio->vioblocking (vio, 0, &dummy);
85
86 while (len > 0)
87 {
88 int wr = send (vio->sd, ptr, len, 0);
89
90 if (wr > 0)
91 {
92 ptr += wr;
93 len -= wr;
94 }
95 else if (errno == EAGAIN)
96 {
97 dSP;
98 PUSHMARK (SP);
99 XPUSHs (OURDATAPTR->corohandle);
100 PUTBACK;
101 call_sv ((SV *)writable, G_VOID | G_DISCARD);
102 }
103 else if (ptr == (char *)p)
104 return -1;
105 else
106 break;
107 }
108
109 return ptr - (char *)p;
110 }
111
112 static int
113 our_close (Vio *vio)
114 {
115 if (vio->read != our_read)
116 croak ("vio.read has unexpected content during unpatch - wtf?");
117
118 if (vio->write != our_write)
119 croak ("vio.write has unexpected content during unpatch - wtf?");
120
121 if (vio->vioclose != our_close)
122 croak ("vio.vioclose has unexpected content during unpatch - wtf?");
123
124 SvREFCNT_dec (OURDATAPTR->corohandle);
125 SvREFCNT_dec (OURDATAPTR->corohandle_sv);
126
127 Safefree (OURDATAPTR);
128
129 vio->read = vio_read;
130 vio->write = vio_write;
131 vio->vioclose = vio_close;
132
133 vio->vioclose (vio);
134 }
135
136 MODULE = Coro::Mysql PACKAGE = Coro::Mysql
137
138 BOOT:
139 {
140 readable = get_cv ("Coro::Mysql::readable", 0);
141 writable = get_cv ("Coro::Mysql::writable", 0);
142 }
143
144 PROTOTYPES: ENABLE
145
146 void
147 _patch (IV sock, int fd, SV *corohandle_sv, SV *corohandle)
148 CODE:
149 {
150 MYSQL *my = (MYSQL *)sock;
151 Vio *vio = my->net.vio;
152 ourdata *our;
153
154 if (fd != my->net.fd)
155 croak ("DBD::mysql fd and libmysql disagree - library mismatch, unsupported transport or API changes?");
156
157 if (fd != vio->sd)
158 croak ("DBD::mysql fd and vio-sd disagree - library mismatch, unsupported transport or API changes?");
159
160 if (vio->vioclose != vio_close)
161 croak ("vio.write has unexpected content - library mismatch, unsupported transport or API changes?");
162
163 if (vio->write != vio_write)
164 croak ("vio.write has unexpected content - library mismatch, unsupported transport or API changes?");
165
166 if (vio->read != vio_read
167 && vio->read != vio_read_buff)
168 croak ("vio.read has unexpected content - library mismatch, unsupported transport or API changes?");
169
170 Newz (0, our, 1, ourdata);
171 our->magic = CoMy_MAGIC;
172 our->corohandle_sv = newSVsv (corohandle_sv);
173 our->corohandle = newSVsv (corohandle);
174
175 vio->desc [DESC_OFFSET - 1] = 0;
176 OURDATAPTR = our;
177
178 vio->vioclose = our_close;
179 vio->write = our_write;
180 vio->read = our_read;
181 }
182