--- 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.
*/