[PATCH BlueZ 2/2] shared/io-glib: Reduce duplicated code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

---
 src/shared/io-glib.c | 264 ++++++++++++++++++---------------------------------
 1 file changed, 94 insertions(+), 170 deletions(-)

diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
index 5ebde3d..af2ba4e 100644
--- a/src/shared/io-glib.c
+++ b/src/shared/io-glib.c
@@ -31,21 +31,20 @@
 
 #include "src/shared/io.h"
 
+struct io_watch {
+	struct io *io;
+	guint id;
+	io_callback_func_t callback;
+	io_destroy_func_t destroy;
+	void *user_data;
+};
+
 struct io {
 	int ref_count;
 	GIOChannel *channel;
-	guint read_watch;
-	io_callback_func_t read_callback;
-	io_destroy_func_t read_destroy;
-	void *read_data;
-	guint write_watch;
-	io_callback_func_t write_callback;
-	io_destroy_func_t write_destroy;
-	void *write_data;
-	guint disconnect_watch;
-	io_callback_func_t disconnect_callback;
-	io_destroy_func_t disconnect_destroy;
-	void *disconnect_data;
+	struct io_watch *read_watch;
+	struct io_watch *write_watch;
+	struct io_watch *disconnect_watch;
 };
 
 static struct io *io_ref(struct io *io)
@@ -87,17 +86,26 @@ struct io *io_new(int fd)
 
 	g_io_channel_set_close_on_unref(io->channel, FALSE);
 
-	io->read_watch = 0;
-	io->read_callback = NULL;
-	io->read_destroy = NULL;
-	io->read_data = NULL;
+	return io_ref(io);
+}
 
-	io->write_watch = 0;
-	io->write_callback = NULL;
-	io->write_destroy = NULL;
-	io->write_data = NULL;
+static void watch_destroy(void *user_data)
+{
+	struct io_watch *watch = user_data;
+	struct io *io = watch->io;
 
-	return io_ref(io);
+	if (watch == io->read_watch)
+		io->read_watch = NULL;
+	else if (watch == io->write_watch)
+		io->write_watch = NULL;
+	else if (watch == io->disconnect_watch)
+		io->disconnect_watch = NULL;
+
+	if (watch->destroy)
+		watch->destroy(watch->user_data);
+
+	io_unref(watch->io);
+	g_free(watch);
 }
 
 void io_destroy(struct io *io)
@@ -105,19 +113,19 @@ void io_destroy(struct io *io)
 	if (!io)
 		return;
 
-	if (io->read_watch > 0) {
-		g_source_remove(io->read_watch);
-		io->read_watch = 0;
+	if (io->read_watch) {
+		g_source_remove(io->read_watch->id);
+		io->read_watch = NULL;
 	}
 
-	if (io->write_watch > 0) {
-		g_source_remove(io->write_watch);
-		io->write_watch = 0;
+	if (io->write_watch) {
+		g_source_remove(io->write_watch->id);
+		io->write_watch = NULL;
 	}
 
-	if (io->disconnect_watch > 0) {
-		g_source_remove(io->disconnect_watch);
-		io->disconnect_watch = 0;
+	if (io->disconnect_watch) {
+		g_source_remove(io->disconnect_watch->id);
+		io->disconnect_watch = NULL;
 	}
 
 	g_io_channel_unref(io->channel);
@@ -147,188 +155,104 @@ bool io_set_close_on_destroy(struct io *io, bool do_close)
 	return true;
 }
 
-static void read_watch_destroy(gpointer user_data)
-{
-	struct io *io = user_data;
-
-	if (io->read_destroy)
-		io->read_destroy(io->read_data);
-
-	io->read_watch = 0;
-	io->read_callback = NULL;
-	io->read_destroy = NULL;
-	io->read_data = NULL;
-
-	io_unref(io);
-}
-
-static gboolean read_callback(GIOChannel *channel, GIOCondition cond,
+static gboolean watch_callback(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
-	struct io *io = user_data;
+	struct io_watch *watch = user_data;
 	bool result;
 
 	if (cond & (G_IO_ERR | G_IO_NVAL))
 		return FALSE;
 
-	if (io->read_callback)
-		result = io->read_callback(io, io->read_data);
+	if (watch->callback)
+		result = watch->callback(watch->io, watch->user_data);
 	else
 		result = false;
 
 	return result ? TRUE : FALSE;
 }
 
-bool io_set_read_handler(struct io *io, io_callback_func_t callback,
-				void *user_data, io_destroy_func_t destroy)
+static struct io_watch *watch_new(struct io *io, GIOCondition cond,
+				io_callback_func_t callback, void *user_data,
+				io_destroy_func_t destroy)
 {
-	if (!io)
-		return false;
+	struct io_watch *watch;
 
-	if (io->read_watch > 0) {
-		g_source_remove(io->read_watch);
-		io->read_watch = 0;
-	}
-
-	if (!callback)
-		goto done;
-
-	io->read_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
-						G_IO_IN | G_IO_ERR | G_IO_NVAL,
-						read_callback, io_ref(io),
-						read_watch_destroy);
-	if (io->read_watch == 0)
-		return false;
-
-	io->read_destroy = destroy;
-	io->read_data = user_data;
-
-done:
-	io->read_callback = callback;
-
-	return true;
-}
-
-static void write_watch_destroy(gpointer user_data)
-{
-	struct io *io = user_data;
-
-	if (io->write_destroy)
-		io->write_destroy(io->write_data);
+	watch = g_try_new0(struct io_watch, 1);
+	if (!watch)
+		return NULL;
 
-	io->write_watch = 0;
-	io->write_callback = NULL;
-	io->write_destroy = NULL;
-	io->write_data = NULL;
+	watch->io = io_ref(io);
+	watch->callback = callback;
+	watch->destroy = destroy;
+	watch->user_data = user_data;
+
+	watch->id = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
+						cond | G_IO_ERR | G_IO_NVAL,
+						watch_callback, watch,
+						watch_destroy);
+	if (watch->id == 0) {
+		watch_destroy(watch);
+		return NULL;
+	}
 
-	io_unref(io);
+	return watch;
 }
 
-static gboolean write_callback(GIOChannel *channel, GIOCondition cond,
-							gpointer user_data)
+static bool io_set_handler(struct io *io, GIOCondition cond,
+				io_callback_func_t callback, void *user_data,
+				io_destroy_func_t destroy)
 {
-	struct io *io = user_data;
-	bool result;
-
-	if (cond & (G_IO_ERR | G_IO_NVAL))
-		return FALSE;
-
-	if (io->write_callback)
-		result = io->write_callback(io, io->write_data);
-	else
-		result = false;
+	struct io_watch **watch;
 
-	return result ? TRUE : FALSE;
-}
-
-bool io_set_write_handler(struct io *io, io_callback_func_t callback,
-				void *user_data, io_destroy_func_t destroy)
-{
 	if (!io)
 		return false;
 
-	if (io->write_watch > 0) {
-		g_source_remove(io->write_watch);
-		io->write_watch = 0;
+	switch (cond) {
+	case G_IO_IN:
+		watch = &io->read_watch;
+		break;
+	case G_IO_OUT:
+		watch = &io->write_watch;
+		break;
+	case G_IO_HUP:
+		watch = &io->disconnect_watch;
+		break;
+	default:
+		return false;
+	}
+
+	if (*watch) {
+		g_source_remove((*watch)->id);
+		*watch = NULL;
 	}
 
 	if (!callback)
-		goto done;
+		return true;
 
-	io->write_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
-						G_IO_OUT | G_IO_ERR | G_IO_NVAL,
-						write_callback, io_ref(io),
-						write_watch_destroy);
-	if (io->write_watch == 0)
+	*watch = watch_new(io, cond, callback, user_data, destroy);
+	if (!*watch)
 		return false;
 
-	io->write_destroy = destroy;
-	io->write_data = user_data;
-
-done:
-	io->write_callback = callback;
-
 	return true;
 }
 
-static void disconnect_watch_destroy(gpointer user_data)
+bool io_set_read_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy)
 {
-	struct io *io = user_data;
-
-	if (io->disconnect_destroy)
-		io->disconnect_destroy(io->disconnect_data);
-
-	io->disconnect_watch = 0;
-	io->disconnect_callback = NULL;
-	io->disconnect_destroy = NULL;
-	io->disconnect_data = NULL;
-
-	io_unref(io);
+	return io_set_handler(io, G_IO_IN, callback, user_data, destroy);
 }
 
-static gboolean disconnect_callback(GIOChannel *channel, GIOCondition cond,
-							gpointer user_data)
+bool io_set_write_handler(struct io *io, io_callback_func_t callback,
+				void *user_data, io_destroy_func_t destroy)
 {
-	struct io *io = user_data;
-	bool result;
-
-	if (io->disconnect_callback)
-		result = io->disconnect_callback(io, io->disconnect_data);
-	else
-		result = false;
-
-	return result ? TRUE : FALSE;
+	return io_set_handler(io, G_IO_OUT, callback, user_data, destroy);
 }
 
 bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
 				void *user_data, io_destroy_func_t destroy)
 {
-	if (!io)
-		return false;
-
-	if (io->disconnect_watch > 0) {
-		g_source_remove(io->disconnect_watch);
-		io->disconnect_watch = 0;
-	}
-
-	if (!callback)
-		goto done;
-
-	io->disconnect_watch = g_io_add_watch_full(io->channel,
-						G_PRIORITY_DEFAULT,
-						G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-						disconnect_callback, io_ref(io),
-						disconnect_watch_destroy);
-	if (io->disconnect_watch == 0)
-		return false;
-
-	io->disconnect_destroy = destroy;
-	io->disconnect_data = user_data;
-
-done:
-	io->disconnect_callback = callback;
-
-	return true;
+	return io_set_handler(io, G_IO_HUP, callback, user_data, destroy);
 }
 
 ssize_t io_send(struct io *io, const struct iovec *iov, int iovcnt)
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux