From c9a37e4a9a3c798582755757af429fe998746112 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 28 Jan 2010 22:05:44 +0100 Subject: [PATCH] Add new constructor for fully blocking operation --- gatchat/gatchat.c | 31 +++++++++++++++++++++++++++---- gatchat/gatchat.h | 1 + gatchat/gatutil.c | 4 ++-- gatchat/gatutil.h | 2 +- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c index f60f857a..dc33beba 100644 --- a/gatchat/gatchat.c +++ b/gatchat/gatchat.c @@ -70,6 +70,7 @@ struct _GAtChat { guint next_notify_id; /* Next notify id */ guint read_watch; /* GSource read id, 0 if none */ guint write_watch; /* GSource write id, 0 if none */ + gboolean use_write_watch; /* watch usage for non blocking */ GIOChannel *channel; /* channel */ GQueue *command_queue; /* Command queue */ guint cmd_bytes_written; /* bytes written from cmd */ @@ -880,14 +881,20 @@ static void g_at_chat_wakeup_writer(GAtChat *chat) if (chat->write_watch != 0) return; - chat->write_watch = g_io_add_watch_full(chat->channel, + if (chat->use_write_watch == TRUE) { + chat->write_watch = g_io_add_watch_full(chat->channel, G_PRIORITY_DEFAULT, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, can_write_data, chat, (GDestroyNotify)write_watcher_destroy_notify); + } else { + while (can_write_data(chat->channel, G_IO_OUT, chat) == TRUE); + write_watcher_destroy_notify(chat); + } } -GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax) +static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags, + GAtSyntax *syntax) { GAtChat *chat; @@ -907,7 +914,13 @@ GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax) chat->next_notify_id = 1; chat->debugf = NULL; - chat->max_read_attempts = 1; + if (flags & G_IO_FLAG_NONBLOCK) { + chat->use_write_watch = TRUE; + chat->max_read_attempts = 1; + } else { + chat->use_write_watch = FALSE; + chat->max_read_attempts = 1; + } chat->buf = ring_buffer_new(4096); @@ -922,7 +935,7 @@ GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax) chat->notify_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)at_notify_destroy); - if (!g_at_util_setup_io(channel)) + if (!g_at_util_setup_io(channel, flags)) goto error; chat->channel = channel; @@ -949,6 +962,16 @@ error: return NULL; } +GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax) +{ + return create_chat(channel, G_IO_FLAG_NONBLOCK, syntax); +} + +GAtChat *g_at_chat_new_blocking(GIOChannel *channel, GAtSyntax *syntax) +{ + return create_chat(channel, 0, syntax); +} + GIOChannel *g_at_chat_get_channel(GAtChat *chat) { if (chat == NULL) diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h index f76fc421..6f4f0b95 100644 --- a/gatchat/gatchat.h +++ b/gatchat/gatchat.h @@ -39,6 +39,7 @@ typedef void (*GAtResultFunc)(gboolean success, GAtResult *result, typedef void (*GAtNotifyFunc)(GAtResult *result, gpointer user_data); GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax); +GAtChat *g_at_chat_new_blocking(GIOChannel *channel, GAtSyntax *syntax); GIOChannel *g_at_chat_get_channel(GAtChat *chat); diff --git a/gatchat/gatutil.c b/gatchat/gatutil.c index dcff4c7b..7ca1d3f9 100644 --- a/gatchat/gatutil.c +++ b/gatchat/gatutil.c @@ -106,7 +106,7 @@ void g_at_util_debug_chat(gboolean in, const char *str, gsize len, g_free(escaped_str); } -gboolean g_at_util_setup_io(GIOChannel *io) +gboolean g_at_util_setup_io(GIOChannel *io, GIOFlags flags) { GIOFlags io_flags; @@ -116,7 +116,7 @@ gboolean g_at_util_setup_io(GIOChannel *io) io_flags = g_io_channel_get_flags(io); - io_flags |= G_IO_FLAG_NONBLOCK; + io_flags |= (flags & G_IO_FLAG_SET_MASK); if (g_io_channel_set_flags(io, io_flags, NULL) != G_IO_STATUS_NORMAL) diff --git a/gatchat/gatutil.h b/gatchat/gatutil.h index 3aa82652..993db457 100644 --- a/gatchat/gatutil.h +++ b/gatchat/gatutil.h @@ -31,7 +31,7 @@ extern "C" { void g_at_util_debug_chat(gboolean in, const char *str, gsize len, GAtDebugFunc debugf, gpointer user_data); -gboolean g_at_util_setup_io(GIOChannel *io); +gboolean g_at_util_setup_io(GIOChannel *io, GIOFlags flags); #ifdef __cplusplus }