Only check for IO Condition before trying another read when the socket is blocking [#23]
authorMikael Hallendal <micke@imendio.com>
Wed, 29 Oct 2008 17:30:01 +0100
changeset 552 137471c948ae
parent 514 31d914756fde
child 555 695c909d0c45
Only check for IO Condition before trying another read when the socket is blocking [#23] In commit 79deb183d we added a check to see if there was more data to be read before trying again. This to avoid having a blocking socket hang on that call until some data became available. However, when using OpenSSL it sometimes reads everything off the TCP socket and buffers it internally which means that the TCP socket will tell us that there is no more data available which leads to us not trying to read from the OpenSSL layer again. In this commit I added a check to see if the socket was blocking before doing this. The long term fix will be that the socket is always going to be in async mode and the synchronous APIs will be handled at a higher level. [#23 responsible:Hallski milestone:Loudmouth 1.4.3 state:resolved]
loudmouth/lm-socket.c
--- a/loudmouth/lm-socket.c	Mon Oct 06 22:00:49 2008 +0200
+++ b/loudmouth/lm-socket.c	Wed Oct 29 17:30:01 2008 +0100
@@ -204,6 +204,8 @@
 			break;
 		case G_IO_STATUS_AGAIN:
 			/* No data readable but we didn't hangup */
+			/* No need to do anything since we will get a new in_event when data is 
+			 * available or writable. */
 			return FALSE;
 			break;
 		case G_IO_STATUS_ERROR:
@@ -225,6 +227,22 @@
 	return TRUE;
 }
 
+/* 
+ * When a non-blocking socket is used we will simply try to read again but when using a blocking socket
+ * it means that the read operation will block in case there is no data available. 
+ * This function checks if the socket is in blocking mode and checks the IO Condition to see whether there
+ * is more data to be read before trying to read again
+ */
+static gboolean
+socket_attempt_another_read (LmSocket *socket, GIOCondition condition)
+{
+	if (socket->blocking) {
+		return (condition & G_IO_IN); 
+	}
+
+	return TRUE;
+}
+
 static gboolean
 socket_in_event (GIOChannel   *source,
 		     GIOCondition  condition,
@@ -240,7 +258,8 @@
 		return FALSE;
 	}
 
-	while ((condition & G_IO_IN) && socket_read_incoming (socket, buf, IN_BUFFER_SIZE, 
+	while (socket_attempt_another_read (socket, condition) && 
+	       socket_read_incoming (socket, buf, IN_BUFFER_SIZE, 
 				     &bytes_read, &hangup, &reason)) {
 		
 		g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "\nRECV [%d]:\n",