modify transport to use the new object_* stuff, along with transport_fd and fifo
authorTero Marttila <terom@fixme.fi>
Thu, 07 May 2009 02:13:50 +0300
changeset 176 6750d50ee8cd
parent 175 a816950a6548
child 177 a74b55104fb9
modify transport to use the new object_* stuff, along with transport_fd and fifo
src/fifo.c
src/transport.c
src/transport_fd.c
src/transport_fd.h
src/transport_internal.h
--- a/src/fifo.c	Thu May 07 02:12:55 2009 +0300
+++ b/src/fifo.c	Thu May 07 02:13:50 2009 +0300
@@ -25,17 +25,6 @@
 };
 
 /**
- * Get a sock_fd pointer from a sock_fifo pointer
- */
-#define FIFO_FD(sock_ptr) (&(sock_ptr)->base_fd)
-
-/**
- * Get a sock_base pointer from a sock_fifo pointer
- */
-#define FIFO_TRANSPORT(sock_ptr) TRANSPORT_FD_BASE(FIFO_FD(sock_ptr))
-
-
-/**
  * (re)open the fifo, closing it if already open, and keeping any event callbacks registered.
  */
 static err_t fifo_open (struct fifo *fifo, error_t *err)
@@ -47,11 +36,11 @@
         RETURN_SET_ERROR_ERRNO(err, ERR_OPEN);
 
     // set the new fd
-    if ((ERROR_CODE(err) = transport_fd_set(FIFO_FD(fifo), _fd)))
+    if ((ERROR_CODE(err) = transport_fd_set(&fifo->base_fd, _fd)))
         return ERROR_CODE(err);
     
     // use default transport event-based behaviour
-    if ((ERROR_CODE(err) = transport_fd_defaults(FIFO_FD(fifo))))
+    if ((ERROR_CODE(err) = transport_fd_defaults(&fifo->base_fd)))
         return ERROR_CODE(err);
 
     // ok
@@ -59,15 +48,17 @@
 }
 
 /**
- * Destroy the fifo, releasing all resources
+ * Deinit the fifo, releasing all resources
  */
-static void fifo_destroy (struct fifo *fifo)
+static void fifo_deinit (struct fifo *fifo)
 {
-    // destroy base
-    transport_fd_destroy(FIFO_FD(fifo));
+    // deinit base
+    transport_fd_deinit(&fifo->base_fd);
 
     // release the path
     free(fifo->path);
+
+    fifo->path = NULL;
 }
 
 /**
@@ -80,7 +71,7 @@
     struct fifo *fifo = transport_check(transport, &fifo_type);
 
     // trap READ_EOF
-    if (transport_fd_methods_read(transport, buf, len, err) != ERR_EOF)
+    if (transport_fd__read(transport, buf, len, err) != ERR_EOF)
         return ERROR_CODE(err);
     
     // re-open it
@@ -100,26 +91,38 @@
 /**
  * sock_stream_methods::release implementation
  */
-static void _fifo_destroy (transport_t *transport)
+static void fifo__deinit (transport_t *transport)
 {
     struct fifo *fifo = transport_check(transport, &fifo_type);
     
-    fifo_destroy(fifo);
+    fifo_deinit(fifo);
 }
 
 /*
  * Our sock_stream_type
  */
 const struct transport_type fifo_type = {
-    .parent                 = &transport_fd_type,
-    .methods                = {
-        .read               = fifo_read,
-        .write              = NULL,
-        .events             = transport_fd_methods_events,
-        .destroy            = _fifo_destroy,
+    .base_type = {
+        .parent     = &transport_fd_type.base_type,
+    },
+    .methods = {
+        .read       = fifo_read,
+        .write      = NULL,
+        .events     = transport_fd__events,
+        .deinit     = fifo__deinit,
     },
 };
 
+/**
+ * Deinit and free
+ */
+static void fifo_destroy (struct fifo *fifo)
+{
+    fifo_deinit(fifo);
+
+    free(fifo);
+}
+
 err_t fifo_open_read (struct transport_info *transport_info, transport_t **transport_ptr, struct event_base *ev_base,
         const char *path, error_t *err)
 {
@@ -134,15 +137,15 @@
         return SET_ERROR(err, ERR_STRDUP);
 
     // init
-    transport_init(FIFO_TRANSPORT(fifo), &fifo_type, transport_info);
-    transport_fd_init(FIFO_FD(fifo), ev_base, TRANSPORT_FD_INVALID);
+    transport_init(&fifo->base_fd.base, &fifo_type, transport_info);
+    transport_fd_init(&fifo->base_fd, ev_base, TRANSPORT_FD_INVALID);
     
     // open the fifo
     if (fifo_open(fifo, err))
         goto error;
 
     // ok
-    *transport_ptr = FIFO_TRANSPORT(fifo);
+    *transport_ptr = &fifo->base_fd.base;
 
     return SUCCESS;
 
--- a/src/transport.c	Thu May 07 02:12:55 2009 +0300
+++ b/src/transport.c	Thu May 07 02:13:50 2009 +0300
@@ -2,46 +2,43 @@
 
 #include <assert.h>
 
+/**
+ * Our own object_type
+ */
+const struct object_type transport_type_type = {
+    .parent     = NULL,
+};
+
 /*
  * Internal API
  */
 void transport_init (transport_t *transport, const struct transport_type *type, const struct transport_info *info)
 {
-    // not already bound
-    assert(!transport->type);
-
+    // init object
+    object_init(&transport->base_obj, &type->base_type);
+    
     // store
-    transport->type = type;
-
     if (info)
         transport->info = *info;
 }
 
 void* transport_check (transport_t *transport, const struct transport_type *type)
 {
-    const struct transport_type *tp_type;
-
-    // sanity check
-    assert(type);
+    // trip as a bug
+    assert(object_check(&transport->base_obj, &type->base_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
+    // ok, cast via void*
     return transport;
 }
 
 void transport_connected (transport_t *transport, const error_t *err, bool direct)
 {
+    const struct transport_type *type = object_type(&transport->base_obj, &transport_type_type);
+
     // update state
     transport->connected = true;
 
-    if (direct || !transport->type->methods._connected) {
+    if (direct || !type->methods._connected) {
         // user callback
         if (err)
             // connect failed
@@ -52,7 +49,7 @@
 
     } else {
         // wrapper method
-        transport->type->methods._connected(transport, err);
+        type->methods._connected(transport, err);
     }
 }
 
@@ -82,12 +79,14 @@
  */
 int transport_read (transport_t *transport, void *buf, size_t len, error_t *err)
 {
+    const struct transport_type *type = object_type(&transport->base_obj, &transport_type_type);
+
     // not readable
-    if (!transport->type->methods.read)
+    if (!type->methods.read)
         return SET_ERROR(err, -1);
 
     // proxy off to method handler
-    if (transport->type->methods.read(transport, buf, &len, err))
+    if (type->methods.read(transport, buf, &len, err))
         return -ERROR_CODE(err);
     
     // return updated 'bytes-read' len
@@ -96,12 +95,14 @@
 
 int transport_write (transport_t *transport, const void *buf, size_t len, error_t *err)
 {
+    const struct transport_type *type = object_type(&transport->base_obj, &transport_type_type);
+
     // XXX: not writeable
-    if (!transport->type->methods.write)
+    if (!type->methods.write)
         return SET_ERROR(err, -1);
 
     // proxy off to method handler
-    if (transport->type->methods.write(transport, buf, &len, err))
+    if (type->methods.write(transport, buf, &len, err))
         return -ERROR_CODE(err);
 
     // return updated 'bytes-written' len
@@ -110,11 +111,12 @@
 
 err_t transport_events (transport_t *transport, short mask)
 {
+    const struct transport_type *type = object_type(&transport->base_obj, &transport_type_type);
     error_t err;
 
     // notify transport
-    if (transport->type->methods.events) {
-        if (transport->type->methods.events(transport, mask, &err))
+    if (type->methods.events) {
+        if (type->methods.events(transport, mask, &err))
             goto error;
     }
 
@@ -136,9 +138,11 @@
 
 void transport_destroy (transport_t *transport)
 {
+    const struct transport_type *type = object_type(&transport->base_obj, &transport_type_type);
+
     // destroy the transport-specific stuff
-    if (transport->type->methods.destroy)
-        transport->type->methods.destroy(transport);
+    if (type->methods.deinit)
+        type->methods.deinit(transport);
 
     // then the transport itself
     free(transport);
--- a/src/transport_fd.c	Thu May 07 02:12:55 2009 +0300
+++ b/src/transport_fd.c	Thu May 07 02:13:50 2009 +0300
@@ -31,7 +31,7 @@
 /**
  * Our transport_methods implementations
  */
-err_t transport_fd_methods_read (transport_t *transport, void *buf, size_t *len, error_t *err)
+err_t transport_fd__read (transport_t *transport, void *buf, size_t *len, error_t *err)
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     int ret;
@@ -61,7 +61,7 @@
     return SUCCESS;
 }
 
-err_t transport_fd_methods_write (transport_t *transport, const void *buf, size_t *len, struct error_info *err)
+err_t transport_fd__write (transport_t *transport, const void *buf, size_t *len, struct error_info *err)
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     int ret;
@@ -95,7 +95,7 @@
     return SUCCESS;
 }
 
-err_t transport_fd_methods_events (transport_t *transport, short ev_mask, error_t *err)
+err_t transport_fd__events (transport_t *transport, short ev_mask, error_t *err)
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
     
@@ -113,20 +113,22 @@
     return (ERROR_CODE(err) = transport_fd_events(fd, mask));
 }
 
-void _transport_fd_destroy (transport_t *transport)
+void transport_fd__deinit (transport_t *transport)
 {
     struct transport_fd *fd = transport_check(transport, &transport_fd_type);
 
-    transport_fd_destroy(fd);
+    transport_fd_deinit(fd);
 }
 
 const struct transport_type transport_fd_type = {
-    .parent     = NULL,
+    .base_type  = {
+        .parent     = NULL,
+    },
     .methods    = {
-        .read       = transport_fd_methods_read,
-        .write      = transport_fd_methods_write,
-        .events     = transport_fd_methods_events,
-        .destroy    = _transport_fd_destroy
+        .read       = transport_fd__read,
+        .write      = transport_fd__write,
+        .events     = transport_fd__events,
+        .deinit     = transport_fd__deinit
     }
 };
 
@@ -353,13 +355,13 @@
     return SUCCESS;
 }
 
-void transport_fd_destroy (struct transport_fd *fd)
+void transport_fd_deinit (struct transport_fd *fd)
 {
     err_t tmp;
 
     // XXX: this might block
     if ((tmp = transport_fd_close(fd)))
-        log_warn_err_code(tmp, "close");
+        log_warn_err(tmp, "close");
 
 }
 
--- a/src/transport_fd.h	Thu May 07 02:12:55 2009 +0300
+++ b/src/transport_fd.h	Thu May 07 02:13:50 2009 +0300
@@ -63,14 +63,14 @@
 /**
  * Implementation of transport_methods::read
  */
-err_t transport_fd_methods_read (transport_t *transport, void *buf, size_t *len, error_t *err);
+err_t transport_fd__read (transport_t *transport, void *buf, size_t *len, error_t *err);
 
 /**
  * Implementation of transport_methods::write.
  *
  * If this gets EAGAIN, it will automatically enable the write event, unless masked out.
  */
-err_t transport_fd_methods_write (transport_t *transport, const void *buf, size_t *len, error_t *err);
+err_t transport_fd__write (transport_t *transport, const void *buf, size_t *len, error_t *err);
 
 /**
  * Implementation of transport_methods::events.
@@ -80,7 +80,14 @@
  * For TRANSPORT_WRITE, the write event will only be enabled if given in the mask, *and* the ev_write event is currently
  * active (via transport_fd_methods_write()); otherwise, the write event will not be enabled.
  */
-err_t transport_fd_methods_events (transport_t *transport, short mask, error_t *err);
+err_t transport_fd__events (transport_t *transport, short mask, error_t *err);
+
+/**
+ * Implementation of transport_methods::deinit.
+ *
+ * This simply calls transport_fd_deinit().
+ */
+void transport_fd__deinit (transport_t *transport);
 
 /**
  * A transport_fd_callback_func that simply invokes the transport_callback user functions.
@@ -155,12 +162,12 @@
 err_t transport_fd_close (struct transport_fd *fd);
 
 /**
- * Destroy the fd immediately.
+ * Deinitialize the transport_fd.
  *
  * This logs a warning if the close() fails.
  *
  * XXX: this may actually block, I think? SO_LINGER?
  */
-void transport_fd_destroy (struct transport_fd *fd);
+void transport_fd_deinit (struct transport_fd *fd);
 
 #endif
--- a/src/transport_internal.h	Thu May 07 02:12:55 2009 +0300
+++ b/src/transport_internal.h	Thu May 07 02:13:50 2009 +0300
@@ -7,65 +7,66 @@
  * The internal interface for transport implementations.
  */ 
 #include "transport.h"
+#include "object.h"
 
 #include <stdbool.h>
 
 /**
- * Method table for implementation stuff.
- *
- * Note that it is the transport's resposibility to implement the behaviour described in transport.h
+ * The object_type for a transport_type
  */
-struct transport_methods {
-    /** For transport_read() */
-    err_t (*read) (transport_t *transport, void *buf, size_t *len, error_t *err);
-
-    /** For transport_write() */
-    err_t (*write) (transport_t *transport, const void *buf, size_t *len, error_t *err);
-
-    /**
-     * The mask of event flags will be set to the given mask if this method is succesfull.
-     *
-     * The old mask is still available in transport::info::ev_mask.
-     */
-    err_t (*events) (transport_t *transport, short mask, error_t *err);
-
-    /** 
-     * Release the transport's internal state, but not the transport itself.
-     *
-     * In other words, this should release everything inside the transport_t, but not free() the transport_t itself.
-     */
-    void (*destroy) (transport_t *transport);
-
-    /**
-     * Used by layered transports to handle transport_connected.
-     *
-     * If this is NULL, transport_connected will call the user callback directly, otherwise, it will proxy through this.
-     *
-     * The \a err param follows the same rules as for transport_connected() - NULL for success, error info otherwise.
-     *
-     * @param transport the transport state
-     * @param err error info if the connect failed
-     */
-    void (*_connected) (transport_t *transport, const error_t *err);
-};
+extern const struct object_type transport_type_type;
 
 /**
  * The definition of a transport type
  */
 struct transport_type {
-    /** Parent type */
-    const struct transport_type *parent;
+    struct object_type base_type;
 
-    /** Method table */
-    struct transport_methods methods;
+    /**
+     * Method table for implementation stuff.
+     *
+     * Note that it is the transport's resposibility to implement the behaviour described in transport.h
+     */
+    struct transport_methods {
+        /** For transport_read() */
+        err_t (*read) (transport_t *transport, void *buf, size_t *len, error_t *err);
+
+        /** For transport_write() */
+        err_t (*write) (transport_t *transport, const void *buf, size_t *len, error_t *err);
+
+        /**
+         * The mask of event flags will be set to the given mask if this method is succesfull.
+         *
+         * The old mask is still available in transport::info::ev_mask.
+         */
+        err_t (*events) (transport_t *transport, short mask, error_t *err);
+
+        /** 
+         * Release the transport's internal state, but not the transport itself.
+         *
+         * In other words, this should release everything inside the transport_t, but not free() the transport_t itself.
+         */
+        void (*deinit) (transport_t *transport);
+
+        /**
+         * Used by layered transports to handle transport_connected.
+         *
+         * If this is NULL, transport_connected will call the user callback directly, otherwise, it will proxy through this.
+         *
+         * The \a err param follows the same rules as for transport_connected() - NULL for success, error info otherwise.
+         *
+         * @param transport the transport state
+         * @param err error info if the connect failed
+         */
+        void (*_connected) (transport_t *transport, const error_t *err);
+    } methods;
 };
 
 /**
  * The base transport type
  */
 struct transport {
-    /** The type info, or NULL if not yet bound */
-    const struct transport_type *type;
+    struct object base_obj;
 
     /** User info */
     struct transport_info info;