modify transport to use the new object_* stuff, along with transport_fd and fifo
--- 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;