memcache/connection.c
changeset 39 0e21a65074a6
parent 38 9894df13b779
child 41 540737bf6bac
--- a/memcache/connection.c	Tue Aug 26 01:30:53 2008 +0300
+++ b/memcache/connection.c	Wed Aug 27 10:11:44 2008 +0300
@@ -1,6 +1,7 @@
 
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <assert.h>
 
 #include "connection.h"
@@ -32,12 +33,15 @@
 }
 
 int memcache_conn_connect (struct memcache_conn *conn) {
-    assert(conn->fd <= 0);
+    assert(conn->fd <= 0 && !conn->is_connected);
     
     // begin connect
     if ((conn->fd = socket_connect_async(conn->server->endpoint, SOCK_STREAM)) == -1)
         goto error;
 
+    // fd 0 should be stdin...
+    assert(conn->fd > 0);
+
     // set up the connect event
     event_set(&conn->ev, conn->fd, EV_WRITE, &_memcache_conn_ev_connect, conn);
 
@@ -59,8 +63,12 @@
     return -1;
 }
 
+int memcache_conn_is_available (struct memcache_conn *conn) {
+    return (conn->fd > 0 && conn->is_connected && conn->req == NULL);
+}
+
 int memcache_conn_do_req (struct memcache_conn *conn, struct memcache_req *req) {
-    assert(conn->fd > 0);
+    assert(conn->fd > 0 && conn->is_connected);
     assert(conn->req == NULL);
 
     // store the req
@@ -77,10 +85,44 @@
  */
 static void _memcache_conn_ev_connect (evutil_socket_t fd, short what, void *arg) {
     struct memcache_conn *conn = arg;
+    int error;
 
-   // XXX: check if the connect() failed
+    if (socket_check_error(fd, &error))
+        goto error;
+
+    if (error)
+        ERROR("connect failed: %s", strerror(error));
+
+    // mark us as succesfully connected
+    conn->is_connected = 1;
 
     // notify the server
     memcache_server_conn_ready(conn->server, conn);
+    
+    // good
+    return;
+
+error:
+    // notify the server
+    memcache_server_conn_dead(conn->server, conn);
 }
 
+void memcache_conn_free (struct memcache_conn *conn) {
+    // ensure that the connection is not considered to be connected anymore
+    assert(!conn->is_connected);
+    
+    // close the fd if needed
+    if (conn->fd > 0) {
+        if (close(conn->fd))
+            PWARNING("close");
+
+        conn->fd = 0;
+    }
+    
+    // ensure that the event is not pending anymore
+    assert(event_pending(&conn->ev, EV_READ|EV_WRITE|EV_TIMEOUT, NULL) == 0);
+    
+    // free it
+    free(conn);
+}
+