gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r15746 - gnunet/src/util


From: gnunet
Subject: [GNUnet-SVN] r15746 - gnunet/src/util
Date: Wed, 22 Jun 2011 14:20:34 +0200

Author: wachs
Date: 2011-06-22 14:20:33 +0200 (Wed, 22 Jun 2011)
New Revision: 15746

Modified:
   gnunet/src/util/server.c
Log:
patch for time out bug


Modified: gnunet/src/util/server.c
===================================================================
--- gnunet/src/util/server.c    2011-06-22 12:15:30 UTC (rev 15745)
+++ gnunet/src/util/server.c    2011-06-22 12:20:33 UTC (rev 15746)
@@ -185,6 +185,22 @@
   struct GNUNET_TIME_Absolute last_activity;
 
   /**
+   *
+   */
+  GNUNET_CONNECTION_TransmitReadyNotify callback;
+
+  /**
+   * callback
+   */
+  void *callback_cls;
+
+  /**
+   * After how long should an idle connection time
+   * out (on write).
+   */
+  struct GNUNET_TIME_Relative idle_timeout;
+
+  /**
    * Number of external entities with a reference to
    * this client object.
    */
@@ -765,11 +781,11 @@
          client->receive_pending = GNUNET_YES;
 #if DEBUG_SERVER
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Server re-enters receive loop.\n");
+                     "Server re-enters receive loop, timeout: %llu.\n", 
client->server->idle_timeout.rel_value);
 #endif
          GNUNET_CONNECTION_receive (client->connection,
                                     GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                                    client->server->idle_timeout, 
+                                    client->idle_timeout,
                                     &process_incoming, client);
          break;
        }
@@ -821,10 +837,29 @@
 {
   struct GNUNET_SERVER_Client *client = cls;
   struct GNUNET_SERVER_Handle *server = client->server;
+  struct GNUNET_TIME_Absolute start;
   int ret;
 
   GNUNET_assert (client->receive_pending == GNUNET_YES);
   client->receive_pending = GNUNET_NO;
+  start = 
GNUNET_TIME_absolute_subtract(GNUNET_TIME_absolute_get(),client->idle_timeout);
+
+
+  if ((buf == NULL) && (available == 0)  && (addr == NULL) && (errCode == 0) &&
+      (client->last_activity.abs_value == GNUNET_TIME_absolute_max(start, 
client->last_activity).abs_value))
+    {
+      // wait longer...
+#if DEBUG_SERVER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Receive time out, but no disconnect due to sending (%p)\n",
+              GNUNET_a2s (addr, addrlen));
+#endif
+      GNUNET_SERVER_client_keep (client);
+      client->last_activity = GNUNET_TIME_absolute_get ();
+      process_mst (client, ret);
+      return;
+    }
+
   if ((buf == NULL) ||
       (available == 0) ||
       (errCode != 0) ||
@@ -879,7 +914,8 @@
       client->receive_pending = GNUNET_YES;
       GNUNET_CONNECTION_receive (client->connection,
                                 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                                client->server->idle_timeout, 
&process_incoming, client);
+                                client->idle_timeout, &process_incoming, 
client);
+
       return;
     }
 #if DEBUG_SERVER
@@ -950,16 +986,35 @@
   client->server = server;
   client->last_activity = GNUNET_TIME_absolute_get ();
   client->next = server->clients;
+  client->idle_timeout = server->idle_timeout;
   server->clients = client;
   client->receive_pending = GNUNET_YES;
+  client->callback = NULL;
+  client->callback_cls = NULL;
   GNUNET_CONNECTION_receive (client->connection,
                             GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                            server->idle_timeout, &process_incoming, client);
+                            client->idle_timeout, &process_incoming, client);
   return client;
 }
 
 
 /**
+ * Change the timeout for a particular client.  Decreasing the timeout
+ * may not go into effect immediately (only after the previous timeout
+ * times out or activity happens on the socket).
+ *
+ * @param client the client to update
+ * @param timeout new timeout for activities on the socket
+ */
+void
+GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
+         struct GNUNET_TIME_Relative timeout)
+{
+  client->idle_timeout = timeout;
+}
+
+
+/**
  * Notify the server that the given client handle should
  * be kept (keeps the connection up if possible, increments
  * the internal reference counter).
@@ -1183,7 +1238,21 @@
   return GNUNET_CONNECTION_disable_corking (client->connection);
 }
 
+size_t transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
+{
+  int ret;
+  struct GNUNET_SERVER_Client *client = cls;
 
+  GNUNET_CONNECTION_TransmitReadyNotify callback = client->callback;
+  void * callback_cls = client->callback_cls;
+
+  client->last_activity = GNUNET_TIME_absolute_get();
+  client->callback = NULL;
+  client->callback_cls = NULL;
+
+  return callback (callback_cls, size, buf);
+}
+
 /**
  * Notify us when the server has enough space to transmit
  * a message of the given size to the given client.
@@ -1206,11 +1275,18 @@
                                      GNUNET_CONNECTION_TransmitReadyNotify
                                      callback, void *callback_cls)
 {
+  GNUNET_assert (client->callback == NULL);
+
+  client->callback_cls = callback_cls;
+  client->callback = callback;
+
   return GNUNET_CONNECTION_notify_transmit_ready (client->connection,
                                                  size,
-                                                 timeout, callback, 
callback_cls);
+                                                 timeout, 
transmit_ready_callback_wrapper, client);
 }
 
+
+
 /**
  * Set the persistent flag on this client, used to setup client connection
  * to only be killed when the service it's connected to is actually dead.




reply via email to

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