diff options
author | Florian Dold <florian.dold@gmail.com> | 2014-02-10 00:13:13 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2014-02-10 00:13:13 +0000 |
commit | f41fa68561b05a68dbcea690fbd10fda7d0d4460 (patch) | |
tree | 8834f2d9cf027ef31720f4bec7bd4ab11eadbdc9 /src | |
parent | 8a6d5d56ba09ddd8a8848bae490b84ef3ea2923d (diff) | |
download | gnunet-f41fa68561b05a68dbcea690fbd10fda7d0d4460.tar.gz gnunet-f41fa68561b05a68dbcea690fbd10fda7d0d4460.zip |
- fix operation cancellation in SET
Diffstat (limited to 'src')
-rw-r--r-- | src/set/gnunet-service-set.c | 23 | ||||
-rw-r--r-- | src/set/set_api.c | 23 | ||||
-rw-r--r-- | src/set/test_set_api.c | 4 |
3 files changed, 38 insertions, 12 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 73d8f95cd..bb0d2ce18 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -224,6 +224,7 @@ listener_destroy (struct Listener *listener) | |||
224 | { | 224 | { |
225 | struct GNUNET_SERVER_Client *client = listener->client; | 225 | struct GNUNET_SERVER_Client *client = listener->client; |
226 | listener->client = NULL; | 226 | listener->client = NULL; |
227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "disconnecting listener client\n"); | ||
227 | GNUNET_SERVER_client_disconnect (client); | 228 | GNUNET_SERVER_client_disconnect (client); |
228 | return; | 229 | return; |
229 | } | 230 | } |
@@ -1053,24 +1054,30 @@ handle_client_cancel (void *cls, | |||
1053 | GNUNET_SERVER_client_disconnect (client); | 1054 | GNUNET_SERVER_client_disconnect (client); |
1054 | return; | 1055 | return; |
1055 | } | 1056 | } |
1057 | |||
1058 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client requested cancel for op %u\n", ntohl (msg->request_id)); | ||
1059 | |||
1056 | found = GNUNET_NO; | 1060 | found = GNUNET_NO; |
1057 | for (op = set->ops_head; NULL != op; op = op->next) | 1061 | for (op = set->ops_head; NULL != op; op = op->next) |
1058 | { | 1062 | { |
1059 | if (op->spec->client_request_id == msg->request_id) | 1063 | if (op->spec->client_request_id == ntohl (msg->request_id)) |
1060 | { | 1064 | { |
1061 | found = GNUNET_YES; | 1065 | found = GNUNET_YES; |
1062 | break; | 1066 | break; |
1063 | } | 1067 | } |
1064 | } | 1068 | } |
1065 | 1069 | ||
1066 | if (GNUNET_NO == found) | 1070 | /* It may happen that the operation was destroyed due to |
1067 | { | 1071 | * the other peer disconnecting. The client may not know about this |
1068 | GNUNET_break (0); | 1072 | * yet and try to cancel the (non non-existent) operation. |
1069 | GNUNET_SERVER_client_disconnect (client); | 1073 | */ |
1070 | return; | 1074 | if (GNUNET_NO != found) |
1071 | } | 1075 | _GSS_operation_destroy (op); |
1076 | else | ||
1077 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client canceled non-existent op\n"); | ||
1072 | 1078 | ||
1073 | _GSS_operation_destroy (op); | 1079 | |
1080 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1074 | } | 1081 | } |
1075 | 1082 | ||
1076 | 1083 | ||
diff --git a/src/set/set_api.c b/src/set/set_api.c index 951ac2b5b..0c9df22e4 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -283,7 +283,13 @@ handle_result (void *cls, const struct GNUNET_MessageHeader *mh) | |||
283 | result_status = ntohs (msg->result_status); | 283 | result_status = ntohs (msg->result_status); |
284 | 284 | ||
285 | oh = GNUNET_MQ_assoc_get (set->mq, ntohl (msg->request_id)); | 285 | oh = GNUNET_MQ_assoc_get (set->mq, ntohl (msg->request_id)); |
286 | GNUNET_assert (NULL != oh); | 286 | // 'oh' can be NULL if we canceled the operation, but the service |
287 | // did not get the cancel message yet. | ||
288 | if (NULL == oh) | ||
289 | { | ||
290 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ignoring result from canceled operation\n"); | ||
291 | return; | ||
292 | } | ||
287 | /* status is not STATUS_OK => there's no attached element, | 293 | /* status is not STATUS_OK => there's no attached element, |
288 | * and this is the last result message we get */ | 294 | * and this is the last result message we get */ |
289 | if (GNUNET_SET_STATUS_OK != result_status) | 295 | if (GNUNET_SET_STATUS_OK != result_status) |
@@ -356,7 +362,7 @@ handle_client_listener_error (void *cls, enum GNUNET_MQ_Error error) | |||
356 | { | 362 | { |
357 | struct GNUNET_SET_ListenHandle *lh = cls; | 363 | struct GNUNET_SET_ListenHandle *lh = cls; |
358 | 364 | ||
359 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "listener broke down, re-connecting\n"); | 365 | LOG (GNUNET_ERROR_TYPE_DEBUG, "listener broke down, re-connecting\n"); |
360 | GNUNET_CLIENT_disconnect (lh->client); | 366 | GNUNET_CLIENT_disconnect (lh->client); |
361 | lh->client = NULL; | 367 | lh->client = NULL; |
362 | GNUNET_MQ_destroy (lh->mq); | 368 | GNUNET_MQ_destroy (lh->mq); |
@@ -381,6 +387,7 @@ set_destroy (struct GNUNET_SET_Handle *set) | |||
381 | set->destroy_requested = GNUNET_YES; | 387 | set->destroy_requested = GNUNET_YES; |
382 | return GNUNET_NO; | 388 | return GNUNET_NO; |
383 | } | 389 | } |
390 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Really destroying set\n"); | ||
384 | GNUNET_CLIENT_disconnect (set->client); | 391 | GNUNET_CLIENT_disconnect (set->client); |
385 | set->client = NULL; | 392 | set->client = NULL; |
386 | GNUNET_MQ_destroy (set->mq); | 393 | GNUNET_MQ_destroy (set->mq); |
@@ -415,16 +422,21 @@ set_operation_cancel (struct GNUNET_SET_OperationHandle *oh) | |||
415 | if (NULL != oh->set) | 422 | if (NULL != oh->set) |
416 | { | 423 | { |
417 | struct GNUNET_SET_OperationHandle *h_assoc; | 424 | struct GNUNET_SET_OperationHandle *h_assoc; |
425 | struct GNUNET_SET_CancelMessage *m; | ||
418 | struct GNUNET_MQ_Envelope *mqm; | 426 | struct GNUNET_MQ_Envelope *mqm; |
419 | 427 | ||
420 | GNUNET_CONTAINER_DLL_remove (oh->set->ops_head, oh->set->ops_tail, oh); | 428 | GNUNET_CONTAINER_DLL_remove (oh->set->ops_head, oh->set->ops_tail, oh); |
421 | h_assoc = GNUNET_MQ_assoc_remove (oh->set->mq, oh->request_id); | 429 | h_assoc = GNUNET_MQ_assoc_remove (oh->set->mq, oh->request_id); |
422 | GNUNET_assert ((h_assoc == NULL) || (h_assoc == oh)); | 430 | GNUNET_assert ((h_assoc == NULL) || (h_assoc == oh)); |
423 | mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_CANCEL); | 431 | mqm = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SET_CANCEL); |
432 | m->request_id = htonl (oh->request_id); | ||
424 | GNUNET_MQ_send (oh->set->mq, mqm); | 433 | GNUNET_MQ_send (oh->set->mq, mqm); |
425 | 434 | ||
426 | if (GNUNET_YES == oh->set->destroy_requested) | 435 | if (GNUNET_YES == oh->set->destroy_requested) |
436 | { | ||
437 | LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying set after operation cancel\n"); | ||
427 | ret = set_destroy (oh->set); | 438 | ret = set_destroy (oh->set); |
439 | } | ||
428 | } | 440 | } |
429 | 441 | ||
430 | GNUNET_free (oh); | 442 | GNUNET_free (oh); |
@@ -451,6 +463,8 @@ handle_client_set_error (void *cls, enum GNUNET_MQ_Error error) | |||
451 | { | 463 | { |
452 | struct GNUNET_SET_Handle *set = cls; | 464 | struct GNUNET_SET_Handle *set = cls; |
453 | 465 | ||
466 | LOG (GNUNET_ERROR_TYPE_DEBUG, "handling client set error\n"); | ||
467 | |||
454 | while (NULL != set->ops_head) | 468 | while (NULL != set->ops_head) |
455 | { | 469 | { |
456 | if (NULL != set->ops_head->result_cb) | 470 | if (NULL != set->ops_head->result_cb) |
@@ -836,6 +850,7 @@ GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, GNUNET_SET_ElementIterator it | |||
836 | { | 850 | { |
837 | struct GNUNET_MQ_Envelope *ev; | 851 | struct GNUNET_MQ_Envelope *ev; |
838 | 852 | ||
853 | |||
839 | GNUNET_assert (NULL != iter); | 854 | GNUNET_assert (NULL != iter); |
840 | 855 | ||
841 | if (GNUNET_YES == set->invalid) | 856 | if (GNUNET_YES == set->invalid) |
@@ -843,6 +858,8 @@ GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, GNUNET_SET_ElementIterator it | |||
843 | if (NULL != set->iterator) | 858 | if (NULL != set->iterator) |
844 | return GNUNET_NO; | 859 | return GNUNET_NO; |
845 | 860 | ||
861 | LOG (GNUNET_ERROR_TYPE_DEBUG, "iterating set\n"); | ||
862 | |||
846 | set->iterator = iter; | 863 | set->iterator = iter; |
847 | set->iterator_cls = cls; | 864 | set->iterator_cls = cls; |
848 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST); | 865 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST); |
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c index ec5226d50..d2a0262c8 100644 --- a/src/set/test_set_api.c +++ b/src/set/test_set_api.c | |||
@@ -241,7 +241,9 @@ run (void *cls, | |||
241 | set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); | 241 | set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); |
242 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id); | 242 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id); |
243 | 243 | ||
244 | /* test if canceling an uncommited request works! */ | 244 | |
245 | |||
246 | ///* test if canceling an uncommited request works! */ | ||
245 | my_oh = GNUNET_SET_prepare (&local_id, &app_id, NULL, 0, | 247 | my_oh = GNUNET_SET_prepare (&local_id, &app_id, NULL, 0, |
246 | GNUNET_SET_RESULT_ADDED, NULL, NULL); | 248 | GNUNET_SET_RESULT_ADDED, NULL, NULL); |
247 | 249 | ||