Separate iochannel implementation from HCConn interface.
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Thu, 2 Jul 2009 23:47:16 +0000 (20:47 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Thu, 2 Jul 2009 23:48:06 +0000 (20:48 -0300)
hcconn.c
hcconn.h
hcconn_internal.h
null.c
popproxy.c
ssl_server.c

index 2297c94..2f035ea 100644 (file)
--- a/hcconn.c
+++ b/hcconn.c
@@ -62,25 +62,37 @@ hc_server_add_watch (int fd,
                        hc_server_watch, cb, hc_server_cb_destroy);
 }
 
+struct channel_layer
+{
+  GIOChannel *channel;
+  guint watch;
+};
+
+
 ssize_t
 hc_conn_channel_read (gpointer data, char *buffer, size_t len)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
   return read (fd, buffer, len);
 }
 
 ssize_t
 hc_conn_channel_write (gpointer data, char *buffer, size_t len)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
   return write (fd, buffer, len);
 }
 
 void
 hc_conn_channel_close (gpointer data)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
+  g_source_remove (layer->watch);
   shutdown (fd, SHUT_RDWR);
+  g_io_channel_unref (layer->channel);
 }
 
 gboolean
@@ -93,22 +105,28 @@ hc_conn_watch (GIOChannel *channel, GIOCondition cond, gpointer data)
   return TRUE;
 }
 
-HCConn *
-hc_conn_new (int fd, HCClientFunc func, gpointer data)
+void
+hc_conn_set_driver_channel (HCConn *conn, int fd)
 {
-  HCConn *conn;
-  conn = g_slice_new (HCConn);
-  conn->channel = g_io_channel_unix_new (fd);
-  conn->func = func;
-  conn->data = data;
-  conn->layer = conn->channel;
+  struct channel_layer *layer = g_slice_new (struct channel_layer);
+  layer->channel = g_io_channel_unix_new (fd);
+  conn->layer = layer;
   conn->read = hc_conn_channel_read;
   conn->write = hc_conn_channel_write;
   conn->close = hc_conn_channel_close;
-  conn->watch = g_io_add_watch (conn->channel, G_IO_IN, hc_conn_watch, conn);
+  layer->watch = g_io_add_watch (layer->channel, G_IO_IN, hc_conn_watch, conn);
   if (conn->func)
     conn->func (conn, HC_EVENT_CONNECT, conn->data);
   fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK);
+}
+
+HCConn *
+hc_conn_new (HCClientFunc func, gpointer data)
+{
+  HCConn *conn;
+  conn = g_slice_new (HCConn);
+  conn->func = func;
+  conn->data = data;
   return conn;
 }
 
@@ -135,8 +153,6 @@ hc_conn_write (HCConn *conn, char *buffer, size_t len)
 void
 hc_conn_close (HCConn *conn)
 {
-  g_source_remove (conn->watch);
   conn->close (conn->layer);
-  g_io_channel_unref (conn->channel);
   g_slice_free (HCConn, conn);
 }
index 3fbbea7..eb444f1 100644 (file)
--- a/hcconn.h
+++ b/hcconn.h
@@ -39,10 +39,12 @@ typedef enum
 
 typedef void (*HCClientFunc) (HCConn *, HCEvent, gpointer);
 
-HCConn * hc_conn_new (int, HCClientFunc, gpointer);
+HCConn * hc_conn_new (HCClientFunc, gpointer);
 ssize_t hc_conn_read (HCConn *, char *, size_t);
 void hc_conn_write (HCConn *, char *, size_t);
 void hc_conn_close (HCConn *);
 void hc_conn_set_callback (HCConn *, HCClientFunc, gpointer);
 
+void hc_conn_set_driver_channel (HCConn *, int);
+
 #endif
index 0dee727..6bb9730 100644 (file)
 
 struct _hc_conn_t
 {
-  GIOChannel *channel;
   HCClientFunc func;
   gpointer data;
   ssize_t (*read) (gpointer, char *, size_t);
   ssize_t (*write) (gpointer, char *, size_t);
   void (*close) (gpointer);
   gpointer layer;
-  guint watch;
 };
 
 ssize_t hc_conn_channel_read (gpointer, char *, size_t);
diff --git a/null.c b/null.c
index 64cb074..a543af8 100644 (file)
--- a/null.c
+++ b/null.c
@@ -49,6 +49,7 @@ static void null_error (net_hook_t* hook)
 static net_hook_t* null_server_hook_new (net_hook_t* client_hook, char *server)
 {
   net_hook_t* hook;
+  int fd;
   hook = g_slice_new (net_hook_t);
   hook->peer = client_hook;
   hook->server = TRUE;
@@ -56,7 +57,9 @@ static net_hook_t* null_server_hook_new (net_hook_t* client_hook, char *server)
   hook->close = null_close;
   hook->read = null_read;
   hook->data = NULL;
-  hook->conn = hc_conn_new (hc_tcp_connect (server, "110"), nethook_event, hook);
+  hook->conn = hc_conn_new (nethook_event, hook);
+  fd = hc_tcp_connect (server, "110");
+  hc_conn_set_driver_channel (hook->conn, fd);
   return hook;
 }
 
index 7f4f5a3..3882f75 100644 (file)
@@ -54,7 +54,8 @@ void new_client (int fd, struct sockaddr* addr, socklen_t saddr, gpointer data)
     }
   g_message ("Received connection from %s.",
              inet_ntoa (((struct sockaddr_in *) addr)->sin_addr));
-  conn = hc_conn_new (fd, NULL, NULL);
+  conn = hc_conn_new (NULL, NULL);
+  hc_conn_set_driver_channel (conn, fd);
   hook = ssl_hook_new (conn, address->server, address->port);
   pop_hook_new (hook);
 }
index 17743e2..270e7bd 100644 (file)
@@ -159,6 +159,7 @@ net_hook_t *
 ssl_server_hook_new (net_hook_t *client_hook, char *server, char *port)
 {
   net_hook_t *hook;
+  int fd;
   hook = g_slice_new (net_hook_t);
   hook->peer = client_hook;
   hook->server = TRUE;
@@ -166,6 +167,8 @@ ssl_server_hook_new (net_hook_t *client_hook, char *server, char *port)
   hook->close = ssl_server_close;
   hook->read = ssl_server_read;
   hook->data = ssl_data_new ();
-  hook->conn = hc_conn_new (hc_tcp_connect (server, port), nethook_event, hook);
+  hook->conn = hc_conn_new (nethook_event, hook);
+  fd = hc_tcp_connect (server, port);
+  hc_conn_set_driver_channel (hook->conn, fd);
   return hook;
 }