15 static void _memcache_conn_bev_write (struct bufferevent *bev, void *arg); |
15 static void _memcache_conn_bev_write (struct bufferevent *bev, void *arg); |
16 static void _memcache_conn_bev_read (struct bufferevent *bev, void *arg); |
16 static void _memcache_conn_bev_read (struct bufferevent *bev, void *arg); |
17 static void _memcache_conn_bev_error (struct bufferevent *bev, short what, void *arg); |
17 static void _memcache_conn_bev_error (struct bufferevent *bev, short what, void *arg); |
18 static void _memcache_conn_ev_write (evutil_socket_t fd, short event, void *arg); |
18 static void _memcache_conn_ev_write (evutil_socket_t fd, short event, void *arg); |
19 |
19 |
|
20 static void memcache_conn_req_done (struct memcache_conn *conn); |
|
21 |
20 struct memcache_conn *memcache_conn_open (struct memcache_server *server) { |
22 struct memcache_conn *memcache_conn_open (struct memcache_server *server) { |
21 struct memcache_conn *conn = NULL; |
23 struct memcache_conn *conn = NULL; |
22 |
24 |
23 if ((conn = calloc(1, sizeof(*conn))) == NULL) |
25 if ((conn = calloc(1, sizeof(*conn))) == NULL) |
24 ERROR("calloc"); |
26 ERROR("calloc"); |
87 |
89 |
88 // tell our bufferevent to send it |
90 // tell our bufferevent to send it |
89 if (bufferevent_enable(conn->bev, EV_WRITE)) |
91 if (bufferevent_enable(conn->bev, EV_WRITE)) |
90 PERROR("bufferevent_enable"); |
92 PERROR("bufferevent_enable"); |
91 |
93 |
|
94 // tell the req that it is underway |
|
95 memcache_req_send(req); |
|
96 |
92 // wait for that to complete |
97 // wait for that to complete |
93 return 0; |
98 return 0; |
94 |
99 |
95 error: |
100 error: |
96 return -1; |
101 return -1; |
183 * We have received some reply data, which should include the complete reply line at some point |
196 * We have received some reply data, which should include the complete reply line at some point |
184 */ |
197 */ |
185 static void _memcache_conn_bev_read (struct bufferevent *bev, void *arg) { |
198 static void _memcache_conn_bev_read (struct bufferevent *bev, void *arg) { |
186 struct memcache_conn *conn = arg; |
199 struct memcache_conn *conn = arg; |
187 struct evbuffer *in_buf = bufferevent_get_input(bev); |
200 struct evbuffer *in_buf = bufferevent_get_input(bev); |
|
201 struct memcache_key key; |
188 char *header_data; |
202 char *header_data; |
189 enum memcache_reply reply_type; |
203 enum memcache_reply reply_type; |
190 int has_data; |
204 int has_data; |
191 |
205 |
192 // ensure that we do indeed have some data |
206 // ensure that we do indeed have some data |
193 assert(evbuffer_get_length(in_buf) > 0); |
207 assert(evbuffer_get_length(in_buf) > 0); |
194 |
208 |
195 // attempt to parse the response header |
209 // attempt to parse the response header |
196 if (memcache_cmd_parse_header(in_buf, &header_data, &reply_type, &conn->req->key, &conn->req->obj, &has_data)) |
210 if (memcache_cmd_parse_header(in_buf, &header_data, &reply_type, &key, &conn->req->obj, &has_data)) |
197 ERROR("memcache_cmd_parse_header"); |
211 ERROR("memcache_cmd_parse_header"); |
198 |
212 |
199 // XXX: read reply data |
213 if (!header_data) { |
|
214 // no complete header received yet |
|
215 return; |
|
216 } |
|
217 |
|
218 // disable reads again |
|
219 if (bufferevent_disable(bev, EV_READ)) |
|
220 PERROR("bufferevent_disable"); |
|
221 |
|
222 // does the reply include data? |
|
223 if (has_data) { |
|
224 // check that they key is the same |
|
225 if (key.len != conn->req->key.len || memcmp(key.buf, conn->req->key.buf, key.len) != 0) |
|
226 ERROR("got reply with wrong key !?!"); |
|
227 |
|
228 // start reading the data (including whatever might be left over in the bufferevent buffer...) |
|
229 // XXX: what if this triggers a req notify before we do? |
|
230 memcache_conn_handle_reply_data(conn, in_buf); |
|
231 |
|
232 } else { |
|
233 // the request is done with |
|
234 memcache_conn_req_done(conn); |
|
235 } |
|
236 |
|
237 // notify the request |
|
238 memcache_req_reply(conn->req, reply_type); |
200 |
239 |
201 error: |
240 error: |
202 // XXX: error handling |
241 // XXX: error handling |
203 return; |
242 return; |
204 } |
243 } |
251 error: |
290 error: |
252 // XXX: error handling |
291 // XXX: error handling |
253 assert(0); |
292 assert(0); |
254 } |
293 } |
255 |
294 |
|
295 /* |
|
296 * Detach the request |
|
297 */ |
|
298 static void memcache_conn_req_done (struct memcache_conn *conn) { |
|
299 // ensure that we do currently have a req |
|
300 assert(conn->req); |
|
301 |
|
302 // have the req detach and check it did so |
|
303 memcache_req_done(conn->req); |
|
304 assert(conn->req->conn == NULL); |
|
305 |
|
306 // we are now available again |
|
307 conn->req = NULL; |
|
308 } |
|
309 |
256 void memcache_conn_free (struct memcache_conn *conn) { |
310 void memcache_conn_free (struct memcache_conn *conn) { |
|
311 // XXX: conn->req? |
|
312 |
257 // ensure that the connection is not considered to be connected anymore |
313 // ensure that the connection is not considered to be connected anymore |
258 assert(!conn->is_connected); |
314 assert(!conn->is_connected); |
259 |
315 |
260 // close the fd if needed |
316 // close the fd if needed |
261 if (conn->fd > 0) { |
317 if (conn->fd > 0) { |