Mantis 1716:
authorChristian Grothoff <christian@grothoff.org>
Mon, 20 Jun 2011 09:24:05 +0000 (09:24 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 20 Jun 2011 09:24:05 +0000 (09:24 +0000)
src/arm/gnunet-service-arm.c
src/include/gnunet_connection_lib.h
src/include/gnunet_network_lib.h
src/include/gnunet_server_lib.h
src/util/connection.c
src/util/network.c
src/util/server.c

index e357668d3f566e168b2d3ddb2b99e4b4ae80216a..c388d0c4270a624d3f91add358323db209e4548b 100644 (file)
@@ -958,6 +958,10 @@ transmit_shutdown_ack (void *cls, size_t size, void *buf)
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Transmitting shutdown ACK.\n"));
 
+  /* Make the connection flushing for the purpose of ACK transmitting,
+     needed on W32 to ensure that the message is even received, harmless
+     on other platforms... */
+  GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client));
   msg = (struct GNUNET_MessageHeader *) buf;
   msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN_ACK);
   msg->size = htons (sizeof (struct GNUNET_MessageHeader));
index 700fef3db8cc8b2d6710dff024ca2bff449afbbd..3184e821b9ca062df877317e6dd51f21f56a9ec8 100644 (file)
@@ -113,6 +113,21 @@ typedef void (*GNUNET_CONNECTION_Receiver) (void *cls,
 void
 GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock);
 
+/**
+ * Disable the "CORK" feature for communication with the given socket,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ * Used to make sure that the last messages sent through the connection
+ * reach the other side before the process is terminated.
+ *
+ * @param sock the connection to make flushing and blocking
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock);
+
+
 /**
  * Create a socket handle by boxing an existing OS socket.  The OS
  * socket should henceforth be no longer used directly.
index 34cb7bc32374a37c67976d994555bbd3c718cbc1..1945d210f8d5ba849707063892b0e4a1999d85cd 100644 (file)
@@ -240,6 +240,17 @@ int GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
 int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc,
                                     int how);
 
+/**
+ * Disable the "CORK" feature for communication with the given socket,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ *
+ * @param desc socket
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc);
+
 
 /**
  * Create a new socket.   Configure it for non-blocking IO and
index ca2041984dc71654d93d870a1dd62110af77abcc..2bb5304430f433cd726702923eea8cbe9853e93a 100644 (file)
@@ -383,6 +383,18 @@ GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h,
 
 
 
+/**
+ * Disable the "CORK" feature for communication with the given client,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.
+ *
+ * @param client handle to the client
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client);
+
+
 /**
  * The tansmit context is the key datastructure for a conveniance API
  * used for transmission of complex results to the client followed
index 80f2cae7f8b33d11e50a556b419aa5be91a45d6f..ef38d99a9fabb7473def22fc8f85354aa568761c 100644 (file)
@@ -301,6 +301,23 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock)
   sock->persist = GNUNET_YES;
 }
 
+
+/**
+ * Disable the "CORK" feature for communication with the given socket,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ * Used to make sure that the last messages sent through the connection
+ * reach the other side before the process is terminated.
+ *
+ * @param sock the connection to make flushing and blocking
+ * @return GNUNET_OK on success
+ */
+int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock)
+{
+  return GNUNET_NETWORK_socket_disable_corking (sock->sock);
+}
+
 /**
  * Create a socket handle by boxing an existing OS socket.  The OS
  * socket should henceforth be no longer used directly.
index 0446d649c7e8dee84b6905769dd0435860cf4e3a..b0669b5b1b74a52302e4db53c2ffb5e6ada11b56 100644 (file)
@@ -721,6 +721,30 @@ GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how)
 }
 
 
+/**
+ * Disable the "CORK" feature for communication with the given socket,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ *
+ * @param desc socket
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc)
+{
+  int value = 0;
+  int ret = 0;
+
+  if (0 != (ret = setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof (value))))
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+  if (0 != (ret = setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof (value))))
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+
+  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
+}
+
+
 /**
  * Reset FD set
  * @param fds fd set
index 33a824e7c8065d9b648da84d59c22767f803df3f..103ca24e7a85141749c238ba5935d32cfeb67f1b 100644 (file)
@@ -1169,6 +1169,21 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
 }
 
 
+/**
+ * Disable the "CORK" feature for communication with the given client,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.
+ *
+ * @param client handle to the client
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
+{
+  return GNUNET_CONNECTION_disable_corking (client->connection);
+}
+
+
 /**
  * Notify us when the server has enough space to transmit
  * a message of the given size to the given client.