ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro-Mysql/Mysql.xs
Revision: 1.2
Committed: Tue Jun 16 17:28:00 2009 UTC (14 years, 11 months ago) by root
Branch: MAIN
Changes since 1.1: +3 -0 lines
Log Message:
*** empty log message ***

File Contents

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