[Top][All Lists]
[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r15746 - gnunet/src/util,
gnunet <=