CONSENSUS/SET: even uglier CADET workarounds
authorFlorian Dold <florian.dold@gmail.com>
Sun, 18 Jun 2017 00:24:03 +0000 (02:24 +0200)
committerFlorian Dold <florian.dold@gmail.com>
Sun, 18 Jun 2017 00:24:03 +0000 (02:24 +0200)
src/consensus/gnunet-service-consensus.c
src/set/gnunet-service-set_union.c

index 4af7199aa925e7cd03756c0fb503e9acb654e900..6b76efb18bdbbe73cde944d95748076047e34934 100644 (file)
@@ -1133,8 +1133,11 @@ set_result_cb (void *cls,
       // XXX: check first if any changes to the underlying
       // set are still pending
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Finishing setop in Task {%s}\n",
-                  debug_str_task_key (&task->key));
+                  "P%u: Finishing setop in Task {%s} (%u/%u)\n",
+                  session->local_peer_idx,
+                  debug_str_task_key (&task->key),
+                  (unsigned int) task->step->finished_tasks,
+                  (unsigned int) task->step->tasks_len);
       if (NULL != output_rfn)
       {
         rfn_commit (output_rfn, task_other_peer (task));
@@ -1470,6 +1473,7 @@ commit_set (struct ConsensusSession *session,
        peers to wait. */
     GNUNET_SET_operation_cancel (setop->op);
     setop->op = NULL;
+    finish_task (task);
   }
 #endif
 }
@@ -2378,6 +2382,13 @@ finish_task (struct TaskEntry *task)
 
   task->step->finished_tasks++;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "P%u: Finishing setop in Task {%s} (now %u/%u tasks finished in step)\n",
+              task->step->session->local_peer_idx,
+              debug_str_task_key (&task->key),
+              (unsigned int) task->step->finished_tasks,
+              (unsigned int) task->step->tasks_len);
+
   if (task->step->finished_tasks == task->step->tasks_len)
     finish_step (task->step);
 }
index 94910dd02efd60291c3887d43520f0123601fb82..3e18bf08ed841ac52db11aafb45ba390d25bc638 100644 (file)
@@ -1381,6 +1381,24 @@ send_client_done (void *cls)
   struct GNUNET_MQ_Envelope *ev;
   struct GNUNET_SET_ResultMessage *rm;
 
+  if (GNUNET_YES == op->state->client_done_sent) {
+    return;
+  }
+
+  if (PHASE_DONE != op->state->phase) {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "union operation failed\n");
+    ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT);
+    rm->result_status = htons (GNUNET_SET_STATUS_FAILURE);
+    rm->request_id = htonl (op->client_request_id);
+    rm->element_type = htons (0);
+    GNUNET_MQ_send (op->set->cs->mq,
+                    ev);
+    return;
+  }
+
+  op->state->client_done_sent = GNUNET_YES;
+
   LOG (GNUNET_ERROR_TYPE_INFO,
        "Signalling client that union operation is done\n");
   ev = GNUNET_MQ_msg (rm,
@@ -1393,22 +1411,6 @@ send_client_done (void *cls)
                   ev);
 }
 
-/**
- * Signal to the client that the operation has finished and
- * destroy the operation.
- *
- * @param cls operation to destroy
- */
-static void
-send_client_done_and_destroy (void *cls)
-{
-  struct Operation *op = cls;
-  send_client_done (cls);
-  /* Will also call the union-specific cancel function. */
-  _GSS_operation_destroy (op,
-                          GNUNET_YES);
-}
-
 
 /**
  * Tests if the operation is finished, and if so notify.
@@ -1449,6 +1451,13 @@ maybe_finish (struct Operation *op)
       struct GNUNET_MQ_Envelope *ev;
 
       op->state->phase = PHASE_DONE;
+      /* FIXME:  temporary hack, send message twice and add notification to second message,
+       * so we can be pretty sure that the other party gets at least one of these
+       * (since tunnel end handler is currently broken).
+       */
+      ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER);
+      GNUNET_MQ_send (op->mq,
+                      ev);
       ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER);
       GNUNET_MQ_notify_sent (ev,
                              &send_client_done,
@@ -1884,6 +1893,13 @@ handle_union_p2p_full_done (void *cls,
       /* We sent the full set, and got the response for that.  We're done. */
       op->state->phase = PHASE_DONE;
       GNUNET_CADET_receive_done (op->channel);
+      /* FIXME:  temporary hack, send message twice and add notification to second message,
+       * so we can be pretty sure that the other party gets at least one of these
+       * (since tunnel end handler is currently broken).
+       */
+      ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER);
+      GNUNET_MQ_send (op->mq,
+                      ev);
       ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER);
       GNUNET_MQ_notify_sent (ev,
                              &send_client_done,
@@ -2409,6 +2425,7 @@ union_copy_state (struct SetState *state)
 static void
 union_channel_death (struct Operation *op)
 {
+  send_client_done (op);
   _GSS_operation_destroy (op,
                           GNUNET_YES);
 }