memcache/connection.c
changeset 42 0e503189af2f
parent 41 540737bf6bac
child 43 e5b714190dee
equal deleted inserted replaced
41:540737bf6bac 42:0e503189af2f
    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;
   118     // ok, wait for the reply
   123     // ok, wait for the reply
   119     return;
   124     return;
   120 
   125 
   121 error:
   126 error:
   122     // XXX: error handling
   127     // XXX: error handling
       
   128     assert(0);
       
   129 }
       
   130 
       
   131 /*
       
   132  * Start reading reply data from the connection
       
   133  */
       
   134 void memcache_conn_handle_reply_data (struct memcache_conn *conn, struct evbuffer *buf) {
       
   135     // XXX: implement
   123     assert(0);
   136     assert(0);
   124 }
   137 }
   125 
   138 
   126 /*
   139 /*
   127  * The connect() has finished
   140  * The connect() has finished
   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) {