RPS: Cleanup datastructures, NULL out freed pointers
authorJulius Bünger <buenger@mytum.de>
Mon, 15 Oct 2018 21:11:31 +0000 (23:11 +0200)
committerJulius Bünger <buenger@mytum.de>
Mon, 15 Oct 2018 21:11:31 +0000 (23:11 +0200)
src/rps/rps-sampler_common.c
src/rps/rps_api.c
src/rps/test_rps.conf

index d004c06a50948ab801bf4056228b0bdcc791ede4..5dbb5315a9dd699fac5bcdf153b9a51ac46c6d82 100644 (file)
@@ -387,6 +387,10 @@ check_n_peers_ready (void *cls,
 {
   struct RPS_SamplerRequestHandle *req_handle = cls;
   (void) id;
+  RPS_sampler_n_rand_peers_ready_cb tmp_cb;
+  struct GNUNET_PeerIdentity *peers;
+  uint32_t num_peers;
+  void *cb_cls;
 
   req_handle->cur_num_peers++;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -400,9 +404,20 @@ check_n_peers_ready (void *cls,
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "returning %" PRIX32 " peers to the client\n",
         req_handle->num_peers);
-    req_handle->callback (req_handle->ids, req_handle->num_peers, req_handle->cls);
 
+    /* Copy pointers and peers temporarily as they
+     * might be deleted from within the callback */
+    tmp_cb = req_handle->callback;
+    num_peers = req_handle->num_peers;
+    peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
+    GNUNET_memcpy (peers,
+                   req_handle->ids,
+                   num_peers * sizeof (struct GNUNET_PeerIdentity));
+    cb_cls = req_handle->cls;
     RPS_sampler_request_cancel (req_handle);
+    req_handle = NULL;
+    tmp_cb (peers, num_peers, cb_cls);
+    GNUNET_free (peers);
   }
 }
 
@@ -493,10 +508,12 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle)
                                    req_handle->sampler->notify_ctx_tail,
                                    i->notify_ctx);
       GNUNET_free (i->notify_ctx);
+      i->notify_ctx = NULL;
     }
     GNUNET_free (i);
   }
   GNUNET_free (req_handle->ids);
+  req_handle->ids = NULL;
   GNUNET_CONTAINER_DLL_remove (req_handle->sampler->req_handle_head,
                                req_handle->sampler->req_handle_tail,
                                req_handle);
index 02d833506608dd1d94d09bd391e8978b5038d639..bce56767826d8bd45a3368c435ba92215d238d1f 100644 (file)
@@ -237,11 +237,14 @@ peers_ready_cb (const struct GNUNET_PeerIdentity *peers,
 {
   struct GNUNET_RPS_Request_Handle *rh = cls;
 
+  rh->sampler_rh = NULL;
   rh->ready_cb (rh->ready_cb_cls,
                 num_peers,
                 peers);
-  // TODO cleanup, sampler, rh, cancel stuff
-  // TODO screw this function. We can give the cb,cls directly to the sampler.
+  GNUNET_RPS_stream_cancel (rh->srh);
+  rh->srh = NULL;
+  RPS_sampler_destroy (rh->sampler);
+  rh->sampler = NULL;
 }
 
 
@@ -421,18 +424,13 @@ void
 GNUNET_RPS_stream_cancel (struct GNUNET_RPS_StreamRequestHandle *srh)
 {
   struct GNUNET_RPS_Handle *rps_handle;
-  struct GNUNET_RPS_StreamRequestHandle *srh_iter;
 
+  GNUNET_assert (NULL != srh);
   rps_handle = srh->rps_handle;
-  srh_iter = rps_handle->stream_requests_head;
-  while (NULL != srh_iter && srh_iter != srh) srh_iter = srh_iter->next;
-  if (NULL != srh_iter)
-  {
-    GNUNET_CONTAINER_DLL_remove (rps_handle->stream_requests_head,
-                                 rps_handle->stream_requests_tail,
-                                 srh);
-    GNUNET_free (srh);
-  }
+  GNUNET_CONTAINER_DLL_remove (rps_handle->stream_requests_head,
+                               rps_handle->stream_requests_tail,
+                               srh);
+  GNUNET_free (srh);
   if (NULL == rps_handle->stream_requests_head) cancel_stream (rps_handle);
 }
 
@@ -480,20 +478,24 @@ handle_stream_input (void *cls,
   struct GNUNET_RPS_Handle *h = cls;
   const struct GNUNET_PeerIdentity *peers;
   uint64_t num_peers;
+  struct GNUNET_RPS_StreamRequestHandle *srh_iter;
+  struct GNUNET_RPS_StreamRequestHandle *srh_next;
 
   peers = (struct GNUNET_PeerIdentity *) &msg[1];
   num_peers = ntohl (msg->num_peers);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received %" PRIu64 " peer(s) from stream input.\n",
        num_peers);
-  for (struct GNUNET_RPS_StreamRequestHandle *srh_iter = h->stream_requests_head;
-       NULL != srh_iter;
-       srh_iter = srh_iter->next)
+  srh_iter = h->stream_requests_head;
+  while (NULL != srh_iter)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Calling srh \n");
+    /* Store next pointer - srh might be removed/freed in callback */
+    srh_next = srh_iter->next;
     srh_iter->ready_cb (srh_iter->ready_cb_cls,
                         num_peers,
                         peers);
+    srh_iter = srh_next;
   }
 
   if (NULL == h->stream_requests_head)
index c559306493e0537fbeb809f0983c1b211628828c..c7ac1f3b889a76904f4ada427e30254969bb5cab 100644 (file)
@@ -1,7 +1,7 @@
 [rps]
 #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --log-file=/tmp/rps/valgrind!gnunet-service-rps!%p
 #PREFIX = valgrind --log-file=/tmp/rps/valgrind!gnunet-service-rps!%p
-#PREFIX = valgrind 
+#PREFIX = valgrind
 UNIXPATH = $GNUNET_TMP/gnunet-service-rps.sock
 HOME = $SERVICEHOME
 # PORT = 2106