[PATCH 2/3] Add handle the case when write buffer is full

Zhenhua Zhang zhenhua.zhang at intel.com
Wed Feb 10 18:56:01 PST 2010


If current write_buf is fulled, put it into the full list and fetch
a new ring buffer from the free list.
---
 gatchat/gatserver.c |   63 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 6e76016..2c160bf 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -132,13 +132,70 @@ static gboolean alloc_free_list(GAtServer *server)
 	return TRUE;
 }
 
+static gboolean replace_write_buf(GAtServer *server)
+{
+	struct ring_buffer *free_buf;
+
+	/* Add current buffer into full list and replace current buffer
+	 * by a new free buffer */
+	server->full_list = g_slist_append(server->full_list,
+						server->write_buf);
+
+	/* All free lists are exhausted. Allocate more free lists */
+	if (!server->free_list) {
+		if (!alloc_free_list(server)) {
+			/* Failed so shutdown the socket */
+			g_at_server_shutdown(server);
+
+			return FALSE;
+		}
+	}
+
+	free_buf = server->free_list->data;
+
+	server->free_list = g_slist_remove(server->free_list, free_buf);
+
+	server->write_buf = free_buf;
+
+	return TRUE;
+}
+
 static void send_common(GAtServer *server, const char *buf)
 {
 	gsize avail = ring_buffer_avail(server->write_buf);
-	gsize len = strlen(buf);
+	gsize towrite = strlen(buf);
+	gsize bytes_written;
+	gsize offset = 0;
+
+	if (avail > towrite) {
+		ring_buffer_write(server->write_buf, buf, towrite);
 
-	if (avail >= len)
-		ring_buffer_write(server->write_buf, buf, len);
+		g_at_server_wakeup_writer(server);
+
+		return;
+	}
+
+	/* Write as much as we can */
+	bytes_written = ring_buffer_write(server->write_buf, buf, avail);
+	towrite -= bytes_written;
+	offset = bytes_written;
+
+	/* If current write buf is full, replace it with next free buffer */
+	if (!replace_write_buf(server))
+		return;
+
+	bytes_written = ring_buffer_write(server->write_buf, buf + offset,
+						towrite);
+	while (bytes_written < towrite) {
+		/* The next free buf is full, replace with next free one */
+		if (!replace_write_buf(server))
+			return;
+
+		towrite -= bytes_written;
+		offset += bytes_written;
+		bytes_written = ring_buffer_write(server->write_buf,
+							buf + offset, towrite);
+	}
 
 	g_at_server_wakeup_writer(server);
 }
-- 
1.6.6.1



More information about the ofono mailing list