implement heirarchial type-checking for transport_check new-transport
authorTero Marttila <terom@fixme.fi>
Tue, 28 Apr 2009 23:10:30 +0300
branchnew-transport
changeset 159 d3e253d7281a
parent 158 b5a5df4f4421
child 160 4f8dc89d7cbb
implement heirarchial type-checking for transport_check
src/sock_gnutls.c
src/sock_tcp.c
src/transport.c
src/transport_fd.c
src/transport_fd.h
src/transport_internal.h
--- a/src/sock_gnutls.c	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/sock_gnutls.c	Tue Apr 28 23:10:30 2009 +0300
@@ -329,6 +329,7 @@
 }
 
 struct transport_type sock_gnutls_type = {
+    .parent                 = &sock_tcp_type,
     .methods                = {
         .read               = sock_gnutls_read,
         .write              = sock_gnutls_write,
--- a/src/sock_tcp.c	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/sock_tcp.c	Tue Apr 28 23:10:30 2009 +0300
@@ -31,6 +31,7 @@
  * Our transport_type
  */
 struct transport_type sock_tcp_type = {
+    .parent                 = &transport_fd_type,
     .methods                = {
         .read               = transport_fd_methods_read,
         .write              = transport_fd_methods_write,
--- a/src/transport.c	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/transport.c	Tue Apr 28 23:10:30 2009 +0300
@@ -19,9 +19,19 @@
 
 void* transport_check (transport_t *transport, const struct transport_type *type)
 {
+    const struct transport_type *tp_type;
+
     // sanity check
-    assert(type && transport->type == type);
+    assert(type);
 
+    // look for a matching type in the transport's type list
+    for (tp_type = transport->type; tp_type; tp_type = tp_type->parent)
+        if (tp_type == type)
+            break;
+    
+    // make sure we found one
+    assert(tp_type);
+    
     // ok
     return transport;
 }
@@ -74,7 +84,7 @@
 {
     // not readable
     if (!transport->type->methods.read)
-        return -1;
+        return SET_ERROR(err, -1);
 
     // proxy off to method handler
     if (transport->type->methods.read(transport, buf, &len, err))
@@ -88,7 +98,7 @@
 {
     // XXX: not writeable
     if (!transport->type->methods.write)
-        return -1;
+        return SET_ERROR(err, -1);
 
     // proxy off to method handler
     if (transport->type->methods.write(transport, buf, &len, err))
--- a/src/transport_fd.c	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/transport_fd.c	Tue Apr 28 23:10:30 2009 +0300
@@ -7,19 +7,23 @@
 #include <assert.h>
 
 /**
- * Our pseudo-transport_type
- */
-static struct transport_type transport_fd_type;
-
-/**
  * Our libevent callback
  */
-static void transport_fd_on_event (evutil_socket_t _fd, short what, void *arg) 
+static void transport_fd_on_event (evutil_socket_t _fd, short ev_what, void *arg) 
 {
     struct transport_fd *fd = arg;
 
     (void) _fd;
 
+    short what = 0;
+
+    // build flags
+    if (ev_what & EV_READ)
+        what |= TRANSPORT_READ;
+
+    if (ev_what & EV_WRITE)
+        what |= TRANSPORT_WRITE;
+
     // invoke user callback
     fd->cb_func(fd, what, fd->cb_arg);
 }
@@ -31,6 +35,8 @@
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     int ret;
+
+    RESET_ERROR(err);
     
     // read(), and detect non-EAGAIN or EOF
     if ((ret = read(fd->fd, buf, *len)) < 0 && errno != EAGAIN)
@@ -60,6 +66,8 @@
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     int ret;
     
+    RESET_ERROR(err);
+    
     // write(), and detect non-EAGAIN or EOF
     if ((ret = write(fd->fd, buf, *len)) < 0 && errno != EAGAIN)
         // unexpected error
@@ -87,19 +95,19 @@
     return SUCCESS;
 }
 
-err_t transport_fd_methods_events (transport_t *transport, short mask, error_t *err)
+err_t transport_fd_methods_events (transport_t *transport, short ev_mask, error_t *err)
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     
-    short _mask = 0;
+    short mask = 0;
 
     // enable read as requested
-    if (mask & TRANSPORT_READ)
-        _mask |= TRANSPORT_READ;
+    if (ev_mask & TRANSPORT_READ)
+        mask |= TRANSPORT_READ;
     
     // enable write if requested and it's currently enabled
-    if ((mask & TRANSPORT_WRITE) && event_pending(fd->ev_write, EV_WRITE, NULL))
-        _mask |= TRANSPORT_WRITE;
+    if ((ev_mask & TRANSPORT_WRITE) && event_pending(fd->ev_write, EV_WRITE, NULL))
+        mask |= TRANSPORT_WRITE;
 
     // set
     return (ERROR_CODE(err) = transport_fd_events(fd, mask));
@@ -112,11 +120,14 @@
     transport_fd_destroy(fd);
 }
 
-const struct transport_methods transport_fd_methods = {
-    .read       = transport_fd_methods_read,
-    .write      = transport_fd_methods_write,
-    .events     = transport_fd_methods_events,
-    .destroy    = _transport_fd_destroy
+const struct transport_type transport_fd_type = {
+    .parent     = NULL,
+    .methods    = {
+        .read       = transport_fd_methods_read,
+        .write      = transport_fd_methods_write,
+        .events     = transport_fd_methods_events,
+        .destroy    = _transport_fd_destroy
+    }
 };
 
 /**
--- a/src/transport_fd.h	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/transport_fd.h	Tue Apr 28 23:10:30 2009 +0300
@@ -17,6 +17,11 @@
 struct transport_fd;
 
 /**
+ * Our transport_type
+ */
+extern const struct transport_type transport_fd_type;
+
+/**
  * Low-level callback
  */
 typedef void (*transport_fd_callback_func) (struct transport_fd *fd, short what, void *arg);
@@ -78,11 +83,6 @@
 err_t transport_fd_methods_events (transport_t *transport, short mask, error_t *err);
 
 /**
- * The transport_methods struct
- */
-extern const struct transport_methods transport_fd_methods;
-
-/**
  * A transport_fd_callback_func that simply invokes the transport_callback user functions.
  *
  * Register with a NULL cb_arg.
--- a/src/transport_internal.h	Tue Apr 28 23:09:28 2009 +0300
+++ b/src/transport_internal.h	Tue Apr 28 23:10:30 2009 +0300
@@ -53,6 +53,9 @@
  * The definition of a transport type
  */
 struct transport_type {
+    /** Parent type */
+    const struct transport_type *parent;
+
     /** Method table */
     struct transport_methods methods;
 };
@@ -83,7 +86,7 @@
 
 /**
  * Check the type of the transport, and return the transport as a void* suitable for casting to the appropriate struct
- * for the type.
+ * for the type, or any of its children.
  *
  * It is a bug to call this with a transport of a different type.
  */