gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r5512 - in libmicrohttpd: . src/daemon


From: gnunet
Subject: [GNUnet-SVN] r5512 - in libmicrohttpd: . src/daemon
Date: Sat, 18 Aug 2007 05:24:25 -0600 (MDT)

Author: grothoff
Date: 2007-08-18 05:24:24 -0600 (Sat, 18 Aug 2007)
New Revision: 5512

Modified:
   libmicrohttpd/ChangeLog
   libmicrohttpd/src/daemon/connection.c
   libmicrohttpd/src/daemon/internal.h
   libmicrohttpd/src/daemon/response.c
Log:
do not busy wait on responses from callbacks (with external select)

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2007-08-18 09:07:12 UTC (rev 5511)
+++ libmicrohttpd/ChangeLog     2007-08-18 11:24:24 UTC (rev 5512)
@@ -1,7 +1,11 @@
 Sat Aug 18 03:06:09 MDT 2007
         Check for out of memory when adding headers to
         responses.  Check for NULL key when looking
-        for headers. - CG
+        for headers.   If a content reader callback
+        for a response returns zero (has no data yet),
+        do not possibly fall into busy waiting when
+        using external select (with internal selects
+        we have no choice).  - CG
 
 Wed Aug 15 01:46:44 MDT 2007
         Extending API to allow timeout of connections.

Modified: libmicrohttpd/src/daemon/connection.c
===================================================================
--- libmicrohttpd/src/daemon/connection.c       2007-08-18 09:07:12 UTC (rev 
5511)
+++ libmicrohttpd/src/daemon/connection.c       2007-08-18 11:24:24 UTC (rev 
5512)
@@ -156,6 +156,58 @@
 }
 
 /**
+ * Prepare the response buffer of this connection for
+ * sending.  Assumes that the response mutex is 
+ * already held.  If the transmission is complete,
+ * this function may close the socket (and return
+ * MHD_NO).
+ * 
+ * @return MHD_NO if readying the response failed
+ */
+static int
+ready_response (struct MHD_Connection *connection)
+{
+  int ret;
+  struct MHD_Response *response;
+
+  response = connection->response;
+  ret = response->crc (response->crc_cls,
+                       connection->messagePos,
+                       response->data,
+                       MIN (response->data_buffer_size,
+                            response->total_size - connection->messagePos));
+  if (ret == -1)
+    {
+      /* end of message, signal other side by closing! */
+      response->total_size = connection->messagePos;
+      CLOSE (connection->socket_fd);
+      connection->socket_fd = -1;
+      return MHD_NO;
+    }
+  response->data_start = connection->messagePos;
+  response->data_size = ret;
+  if (ret == 0)
+    {
+      /* avoid busy-waiting when using external select
+         (we assume that the main application will 
+         wake up the external select once more data
+         is ready).  With internal selects, we
+         have no choice; if the app uses a thread
+         per connection, ret==0 is likely a bug --
+         the application should block until data
+         is ready! */
+      if ((0 ==
+           (connection->daemon->
+            options & (MHD_USE_SELECT_INTERNALLY |
+                       MHD_USE_THREAD_PER_CONNECTION))))
+        connection->response_unready = MHD_YES;
+      return MHD_NO;
+    }
+  connection->response_unready = MHD_NO;
+  return MHD_YES;
+}
+
+/**
  * Obtain the select sets for this connection
  *
  * @return MHD_YES on success
@@ -205,8 +257,17 @@
             }
         }
     }
-  if ((connection->response != NULL) || MHD_need_100_continue (connection))
+  if ((connection->response != NULL) &&
+      (connection->response_unready == MHD_YES))
     {
+      pthread_mutex_lock (&connection->response->mutex);
+      ready_response (connection);
+      pthread_mutex_unlock (&connection->response->mutex);
+    }
+  if (((connection->response != NULL) &&
+       (connection->response_unready == MHD_NO)) ||
+      MHD_need_100_continue (connection))
+    {
       FD_SET (fd, write_fd_set);
       if (fd > *max_fd)
         *max_fd = fd;
@@ -1090,32 +1151,10 @@
   if ((response->crc != NULL) &&
       ((response->data_start > connection->messagePos) ||
        (response->data_start + response->data_size <=
-        connection->messagePos)))
+        connection->messagePos)) && (MHD_YES != ready_response (connection)))
     {
-      ret = response->crc (response->crc_cls,
-                           connection->messagePos,
-                           response->data,
-                           MIN (response->data_buffer_size,
-                                response->total_size -
-                                connection->messagePos));
-      if (ret == -1)
-        {
-          /* end of message, signal other side by closing! */
-          response->total_size = connection->messagePos;
-          CLOSE (connection->socket_fd);
-          connection->socket_fd = -1;
-          if (response->crc != NULL)
-            pthread_mutex_unlock (&response->mutex);
-          return MHD_YES;
-        }
-      response->data_start = connection->messagePos;
-      response->data_size = ret;
-      if (ret == 0)
-        {
-          if (response->crc != NULL)
-            pthread_mutex_unlock (&response->mutex);
-          return MHD_YES;
-        }
+      pthread_mutex_unlock (&response->mutex);
+      return MHD_YES;
     }
   /* transmit */
   ret = SEND (connection->socket_fd,

Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2007-08-18 09:07:12 UTC (rev 5511)
+++ libmicrohttpd/src/daemon/internal.h 2007-08-18 11:24:24 UTC (rev 5512)
@@ -347,6 +347,15 @@
    */
   unsigned int responseCode;
 
+  /**
+   * Set to MHD_YES if the response's content reader
+   * callback failed to provide data the last time
+   * we tried to read from it.  In that case, the 
+   * write socket should be marked as unready until
+   * the CRC call succeeds.
+   */
+  int response_unready;
+
 };
 
 

Modified: libmicrohttpd/src/daemon/response.c
===================================================================
--- libmicrohttpd/src/daemon/response.c 2007-08-18 09:07:12 UTC (rev 5511)
+++ libmicrohttpd/src/daemon/response.c 2007-08-18 11:24:24 UTC (rev 5512)
@@ -53,16 +53,18 @@
   if (hdr == NULL)
     return MHD_NO;
   hdr->header = strdup (header);
-  if (hdr->header == NULL) {
-    free(hdr);
-    return MHD_NO;
-  }
+  if (hdr->header == NULL)
+    {
+      free (hdr);
+      return MHD_NO;
+    }
   hdr->value = strdup (content);
-  if (hdr->value == NULL) {
-    free(hdr->header);
-    free(hdr);
-    return MHD_NO;
-  }
+  if (hdr->value == NULL)
+    {
+      free (hdr->header);
+      free (hdr);
+      return MHD_NO;
+    }
   hdr->kind = MHD_HEADER_KIND;
   hdr->next = response->first_header;
   response->first_header = hdr;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]