[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r38019 - gnunet/src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r38019 - gnunet/src/util |
Date: |
Mon, 26 Sep 2016 16:50:20 +0200 |
Author: grothoff
Date: 2016-09-26 16:50:19 +0200 (Mon, 26 Sep 2016)
New Revision: 38019
Modified:
gnunet/src/util/service_new.c
Log:
fix #4680
Modified: gnunet/src/util/service_new.c
===================================================================
--- gnunet/src/util/service_new.c 2016-09-26 14:33:57 UTC (rev 38018)
+++ gnunet/src/util/service_new.c 2016-09-26 14:50:19 UTC (rev 38019)
@@ -255,6 +255,12 @@
struct GNUNET_SCHEDULER_Task *warn_task;
/**
+ * Task run to finish dropping the client after the stack has
+ * properly unwound.
+ */
+ struct GNUNET_SCHEDULER_Task *drop_task;
+
+ /**
* Task that receives data from the client to
* pass it to the handlers.
*/
@@ -1951,7 +1957,7 @@
*
* @param cls closure with the `struct GNUNET_SERVICE_Client *`
* @param message the actual message
- * @return #GNUNET_OK on success (always)
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
*/
static int
service_client_mst_cb (void *cls,
@@ -1970,6 +1976,8 @@
client);
GNUNET_MQ_inject_message (client->mq,
message);
+ if (NULL != client->drop_task)
+ return GNUNET_SYSERR;
return GNUNET_OK;
}
@@ -1994,8 +2002,11 @@
if (GNUNET_SYSERR == ret)
{
/* client closed connection (or IO error) */
- GNUNET_assert (GNUNET_NO == client->needs_continue);
- GNUNET_SERVICE_client_drop (client);
+ if (NULL == client->drop_task)
+ {
+ GNUNET_assert (GNUNET_NO == client->needs_continue);
+ GNUNET_SERVICE_client_drop (client);
+ }
return;
}
if (GNUNET_NO == ret)
@@ -2313,6 +2324,35 @@
/**
+ * Asynchronously finish dropping the client.
+ *
+ * @param cls the `struct GNUNET_SERVICE_Client`.
+ */
+static void
+finish_client_drop (void *cls)
+{
+ struct GNUNET_SERVICE_Client *c = cls;
+ struct GNUNET_SERVICE_Handle *sh = c->sh;
+
+ GNUNET_MST_destroy (c->mst);
+ GNUNET_MQ_destroy (c->mq);
+ if (GNUNET_NO == c->persist)
+ {
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_NETWORK_socket_close (c->sock));
+ }
+ else
+ {
+ GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
+ }
+ GNUNET_free (c);
+ if ( (GNUNET_YES == sh->got_shutdown) &&
+ (GNUNET_NO == have_non_monitor_clients (sh)) )
+ GNUNET_SERVICE_shutdown (sh);
+}
+
+
+/**
* Ask the server to disconnect from the given client. This is the
* same as returning #GNUNET_SYSERR within the check procedure when
* handling a message, wexcept that it allows dropping of a client even
@@ -2327,6 +2367,12 @@
{
struct GNUNET_SERVICE_Handle *sh = c->sh;
+ if (NULL != c->drop_task)
+ {
+ /* asked to drop twice! */
+ GNUNET_break (0);
+ return;
+ }
GNUNET_CONTAINER_DLL_remove (sh->clients_head,
sh->clients_tail,
c);
@@ -2348,21 +2394,8 @@
GNUNET_SCHEDULER_cancel (c->send_task);
c->send_task = NULL;
}
- GNUNET_MST_destroy (c->mst);
- GNUNET_MQ_destroy (c->mq);
- if (GNUNET_NO == c->persist)
- {
- GNUNET_break (GNUNET_OK ==
- GNUNET_NETWORK_socket_close (c->sock));
- }
- else
- {
- GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
- }
- GNUNET_free (c);
- if ( (GNUNET_YES == sh->got_shutdown) &&
- (GNUNET_NO == have_non_monitor_clients (sh)) )
- GNUNET_SERVICE_shutdown (sh);
+ c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop,
+ c);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r38019 - gnunet/src/util,
gnunet <=