Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / set / gnunet-service-set.c
index 3e6e0791a8fc5ed8c22d2a1b21d923cf204b8bd0..b0f8b209186c1ee4a89036ddb2f04b06df2638bd 100644 (file)
@@ -223,6 +223,9 @@ listener_destroy (struct Listener *listener)
   {
     struct GNUNET_SERVICE_Client *client = listener->client;
 
+    GNUNET_MQ_destroy (listener->client_mq);
+    listener->client_mq = NULL;
+
     listener->client = NULL;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Disconnecting listener client\n");
@@ -233,7 +236,6 @@ listener_destroy (struct Listener *listener)
   GNUNET_CONTAINER_DLL_remove (listeners_head,
                                listeners_tail,
                                listener);
-  *listener = (struct Listener) { 0 };
   GNUNET_free (listener);
 }
 
@@ -611,42 +613,6 @@ client_connect_cb (void *cls,
 }
 
 
-/**
- * Clean up after a client has disconnected
- *
- * @param cls closure, unused
- * @param client the client to clean up after
- * @param internal_cls our client-specific internal data structure
- */
-static void
-client_disconnect_cb (void *cls,
-                      struct GNUNET_SERVICE_Client *client,
-                      void *internal_cls)
-{
-  struct Listener *listener;
-  struct Set *set;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "client disconnected, cleaning up\n");
-  set = set_get (client);
-  if (NULL != set)
-  {
-    set->client = NULL;
-    set_destroy (set);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Client's set destroyed\n");
-  }
-  listener = listener_get (client);
-  if (NULL != listener)
-  {
-    listener->client = NULL;
-    listener_destroy (listener);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Client's listener destroyed\n");
-  }
-}
-
-
 /**
  * Destroy an incoming request from a remote peer
  *
@@ -681,6 +647,52 @@ incoming_destroy (struct Operation *incoming)
 }
 
 
+/**
+ * Clean up after a client has disconnected
+ *
+ * @param cls closure, unused
+ * @param client the client to clean up after
+ * @param internal_cls our client-specific internal data structure
+ */
+static void
+client_disconnect_cb (void *cls,
+                      struct GNUNET_SERVICE_Client *client,
+                      void *internal_cls)
+{
+  struct Set *set;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "client disconnected, cleaning up\n");
+  set = set_get (client);
+  if (NULL != set)
+  {
+    set->client = NULL;
+    set_destroy (set);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Client's set destroyed\n");
+  }
+  struct Listener *listener = listener_get (client);
+  struct Operation *op = incoming_head;
+  if (NULL != listener)
+  {
+    /* destroy all incoming operations whose client just
+     * got destroyed */
+    while (NULL != op)
+    {
+      struct Operation *curr = op;
+      op = op->next;
+      if ( (GNUNET_YES == curr->is_incoming) && 
+           (curr->listener == listener) )
+        incoming_destroy (curr);
+    }
+    listener->client = NULL;
+    listener_destroy (listener);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Client's listener destroyed\n");
+  }
+}
+
+
 /**
  * Suggest the given request to the listener. The listening client can
  * then accept or reject the remote request.