From 14425eae4ebeffa88630b5a3e4bdb0ea1b4da325 Mon Sep 17 00:00:00 2001
From: Andy Green <andy.green@linaro.org>
Date: Mon, 18 Aug 2014 22:49:39 +0800
Subject: [PATCH] introduce lws_partial_buffered

Signed-off-by: Andy Green <andy.green@linaro.org>
---
 changelog                 |  6 ++++++
 lib/libwebsockets.c       | 23 +++++++++++++++++++++++
 lib/libwebsockets.h       |  3 +++
 test-server/test-server.c |  8 ++++++--
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/changelog b/changelog
index 95e61940..f50d87bc 100644
--- a/changelog
+++ b/changelog
@@ -21,6 +21,12 @@ over ssl or not.  If LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT is used, both
 ssl and non-ssl connections are possible and may need to be treated differently
 in the user code.
 
+int lws_partial_buffered(wsi) added... should be checked after any
+libwebsocket_write that will be followed by another libwebsocket_write inside
+the same writeable callback.  If set, you can't do any more writes until the
+writeable callback is called again.  If you only do one write per writeable callback,
+you can ignore this.
+
 
 User api removal
 ----------------
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index a5ec698b..166dd3c5 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -769,3 +769,26 @@ lws_is_ssl(struct libwebsocket *wsi)
 {
 	return wsi->use_ssl;
 }
+
+/**
+ * lws_partial_buffered() - find out if lws buffered the last write
+ * @wsi:	websocket connection to check
+ *
+ * Returns 1 if you cannot use libwebsocket_write because the last
+ * write on this connection is still buffered, and can't be cleared without
+ * returning to the service loop and waiting for the connection to be
+ * writeable again.
+ * 
+ * If you will try to do >1 libwebsocket_write call inside a single
+ * WRITEABLE callback, you must check this after every write and bail if
+ * set, ask for a new writeable callback and continue writing from there.
+ * 
+ * This is never set at the start of a writeable callback, but any write
+ * may set it.
+ */
+
+LWS_VISIBLE int
+lws_partial_buffered(struct libwebsocket *wsi)
+{
+	return !!wsi->truncated_send_len;	
+}
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index a0c500ac..7b5e6979 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1169,6 +1169,9 @@ lws_daemonize(const char *_lock_path);
 LWS_VISIBLE LWS_EXTERN int
 lws_send_pipe_choked(struct libwebsocket *wsi);
 
+LWS_VISIBLE LWS_EXTERN int
+lws_partial_buffered(struct libwebsocket *wsi);
+
 LWS_VISIBLE LWS_EXTERN int
 lws_frame_is_binary(struct libwebsocket *wsi);
 
diff --git a/test-server/test-server.c b/test-server/test-server.c
index 682bb5d3..c43b9c45 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -386,13 +386,17 @@ static int callback_http(struct libwebsocket_context *context,
 			if (m) /* while still active, extend timeout */
 				libwebsocket_set_timeout(wsi,
 					PENDING_TIMEOUT_HTTP_CONTENT, 5);
+			
+			/* if he has indigestion, let him clear it before eating more */
+			if (lws_partial_buffered(wsi))
+				break;
 
 		} while (!lws_send_pipe_choked(wsi));
 		libwebsocket_callback_on_writable(context, wsi);
 		break;
 flush_bail:
 		/* true if still partial pending */
-		if (lws_send_pipe_choked(wsi)) {
+		if (lws_partial_buffered(wsi)) {
 			libwebsocket_callback_on_writable(context, wsi);
 			break;
 		}
@@ -632,7 +636,7 @@ callback_lws_mirror(struct libwebsocket_context *context,
 
 			// lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1));
 
-			if (lws_send_pipe_choked(wsi)) {
+			if (lws_partial_buffered(wsi) || lws_send_pipe_choked(wsi)) {
 				libwebsocket_callback_on_writable(context, wsi);
 				break;
 			}
-- 
GitLab