diff options
-rw-r--r-- | src/util/client.c | 152 | ||||
-rw-r--r-- | src/util/connection.c | 26 | ||||
-rw-r--r-- | src/util/server.c | 30 | ||||
-rw-r--r-- | src/util/service.c | 55 | ||||
-rw-r--r-- | src/util/test_server.c | 4 | ||||
-rw-r--r-- | src/util/test_service.c | 17 |
6 files changed, 264 insertions, 20 deletions
diff --git a/src/util/client.c b/src/util/client.c index 86b36bfbb..1b6f46d52 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -136,6 +136,46 @@ struct TransmitGetResponseContext | |||
136 | void *rn_cls; | 136 | void *rn_cls; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /** | ||
140 | * Context for handling the shutdown of a service. | ||
141 | */ | ||
142 | struct ShutdownContext | ||
143 | { | ||
144 | /** | ||
145 | * Scheduler to be used to call continuation | ||
146 | */ | ||
147 | struct GNUNET_SCHEDULER_Handle *sched; | ||
148 | /** | ||
149 | * Connection to the service that is being shutdown. | ||
150 | */ | ||
151 | struct GNUNET_CLIENT_Connection *sock; | ||
152 | |||
153 | /** | ||
154 | * Time allowed for shutdown to happen. | ||
155 | */ | ||
156 | struct GNUNET_TIME_Absolute timeout; | ||
157 | |||
158 | /** | ||
159 | * Task set up to cancel the shutdown request on timeout. | ||
160 | */ | ||
161 | GNUNET_SCHEDULER_TaskIdentifier cancel_task; | ||
162 | |||
163 | /** | ||
164 | * Task to call once shutdown complete | ||
165 | */ | ||
166 | GNUNET_CLIENT_ShutdownTask cont; | ||
167 | |||
168 | /** | ||
169 | * Closure for shutdown continuation | ||
170 | */ | ||
171 | void *cont_cls; | ||
172 | |||
173 | /** | ||
174 | * We received a confirmation that the service will shut down. | ||
175 | */ | ||
176 | int confirmed; | ||
177 | |||
178 | }; | ||
139 | 179 | ||
140 | /** | 180 | /** |
141 | * Struct to refer to a GNUnet TCP connection. | 181 | * Struct to refer to a GNUnet TCP connection. |
@@ -541,6 +581,85 @@ GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, | |||
541 | 581 | ||
542 | 582 | ||
543 | /** | 583 | /** |
584 | * Handler receiving response to service shutdown requests. | ||
585 | * First call with NULL: service misbehaving, or something. | ||
586 | * First call with GNUNET_MESSAGE_TYPE_SHUTDOWN_ACK: | ||
587 | * - service will shutdown | ||
588 | * First call with GNUNET_MESSAGE_TYPE_SHUTDOWN_REFUSE: | ||
589 | * - service will not be stopped! | ||
590 | * | ||
591 | * Second call with NULL: | ||
592 | * - service has now really shut down. | ||
593 | * | ||
594 | * @param cls closure | ||
595 | * @param msg NULL, indicating socket closure. | ||
596 | */ | ||
597 | static void | ||
598 | service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
599 | { | ||
600 | struct ShutdownContext *shutdown_ctx = cls; | ||
601 | |||
602 | if ((msg == NULL) && (shutdown_ctx->confirmed != GNUNET_YES)) /* Means the other side closed the connection and never confirmed a shutdown */ | ||
603 | { | ||
604 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Service handle shutdown before ACK!\n"); | ||
605 | if (shutdown_ctx->cont != NULL) | ||
606 | shutdown_ctx->cont(shutdown_ctx->cont_cls, GNUNET_SYSERR); | ||
607 | |||
608 | GNUNET_SCHEDULER_cancel(shutdown_ctx->sched, shutdown_ctx->cancel_task); | ||
609 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); | ||
610 | GNUNET_free(shutdown_ctx); | ||
611 | } | ||
612 | else if ((msg == NULL) && (shutdown_ctx->confirmed == GNUNET_YES)) | ||
613 | { | ||
614 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); | ||
615 | if (shutdown_ctx->cont != NULL) | ||
616 | shutdown_ctx->cont(shutdown_ctx->cont_cls, GNUNET_NO); | ||
617 | |||
618 | GNUNET_SCHEDULER_cancel(shutdown_ctx->sched, shutdown_ctx->cancel_task); | ||
619 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); | ||
620 | GNUNET_free(shutdown_ctx); | ||
621 | } | ||
622 | else | ||
623 | { | ||
624 | GNUNET_assert(ntohs(msg->size) == sizeof(struct GNUNET_MessageHeader)); | ||
625 | |||
626 | switch (ntohs(msg->type)) | ||
627 | { | ||
628 | case GNUNET_MESSAGE_TYPE_SHUTDOWN_ACK: | ||
629 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received confirmation for service shutdown.\n"); | ||
630 | shutdown_ctx->confirmed = GNUNET_YES; | ||
631 | GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); | ||
632 | break; | ||
633 | case GNUNET_MESSAGE_TYPE_SHUTDOWN_REFUSE: | ||
634 | default: /* Fall through */ | ||
635 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Service shutdown refused!\n"); | ||
636 | if (shutdown_ctx->cont != NULL) | ||
637 | shutdown_ctx->cont(shutdown_ctx->cont_cls, GNUNET_YES); | ||
638 | |||
639 | GNUNET_SCHEDULER_cancel(shutdown_ctx->sched, shutdown_ctx->cancel_task); | ||
640 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); | ||
641 | GNUNET_free(shutdown_ctx); | ||
642 | break; | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * Shutting down took too long, cancel receive and return error. | ||
649 | * | ||
650 | * @param cls closure | ||
651 | * @param tc context information (why was this task triggered now) | ||
652 | */ | ||
653 | void service_shutdown_cancel (void *cls, | ||
654 | const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
655 | { | ||
656 | struct ShutdownContext *shutdown_ctx = cls; | ||
657 | fprintf(stderr, "service_shutdown_cancel called!\n"); | ||
658 | shutdown_ctx->cont(shutdown_ctx->cont_cls, GNUNET_SYSERR); | ||
659 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); | ||
660 | GNUNET_free(shutdown_ctx); | ||
661 | } | ||
662 | /** | ||
544 | * If possible, write a shutdown message to the target | 663 | * If possible, write a shutdown message to the target |
545 | * buffer and destroy the client connection. | 664 | * buffer and destroy the client connection. |
546 | * | 665 | * |
@@ -553,15 +672,21 @@ static size_t | |||
553 | write_shutdown (void *cls, size_t size, void *buf) | 672 | write_shutdown (void *cls, size_t size, void *buf) |
554 | { | 673 | { |
555 | struct GNUNET_MessageHeader *msg; | 674 | struct GNUNET_MessageHeader *msg; |
556 | struct GNUNET_CLIENT_Connection *sock = cls; | 675 | struct ShutdownContext *shutdown_ctx = cls; |
557 | 676 | ||
558 | GNUNET_CLIENT_disconnect (sock, GNUNET_YES); | ||
559 | if (size < sizeof (struct GNUNET_MessageHeader)) | 677 | if (size < sizeof (struct GNUNET_MessageHeader)) |
560 | { | 678 | { |
561 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 679 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
562 | _("Failed to transmit shutdown request to client.\n")); | 680 | _("Failed to transmit shutdown request to client.\n")); |
681 | |||
682 | shutdown_ctx->cont(shutdown_ctx->cont_cls, GNUNET_SYSERR); | ||
683 | GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); | ||
684 | GNUNET_free(shutdown_ctx); | ||
563 | return 0; /* client disconnected */ | 685 | return 0; /* client disconnected */ |
564 | } | 686 | } |
687 | |||
688 | GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); | ||
689 | shutdown_ctx->cancel_task = GNUNET_SCHEDULER_add_delayed (shutdown_ctx->sched, GNUNET_TIME_absolute_get_remaining(shutdown_ctx->timeout), &service_shutdown_cancel, shutdown_ctx); | ||
565 | msg = (struct GNUNET_MessageHeader *) buf; | 690 | msg = (struct GNUNET_MessageHeader *) buf; |
566 | msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN); | 691 | msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN); |
567 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | 692 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); |
@@ -576,16 +701,33 @@ write_shutdown (void *cls, size_t size, void *buf) | |||
576 | * be used by the caller after this call | 701 | * be used by the caller after this call |
577 | * (calling this function frees "sock" after a while). | 702 | * (calling this function frees "sock" after a while). |
578 | * | 703 | * |
704 | * @param sched the scheduler to use for calling shutdown continuation | ||
579 | * @param sock the socket connected to the service | 705 | * @param sock the socket connected to the service |
706 | * @param timeout how long to wait before giving up on transmission | ||
707 | * @param cont continuation to call once the service is really down | ||
708 | * @param cont_cls closure for continuation | ||
709 | * | ||
580 | */ | 710 | */ |
581 | void | 711 | void |
582 | GNUNET_CLIENT_service_shutdown (struct GNUNET_CLIENT_Connection *sock) | 712 | GNUNET_CLIENT_service_shutdown (struct GNUNET_SCHEDULER_Handle *sched, |
713 | struct GNUNET_CLIENT_Connection *sock, | ||
714 | struct GNUNET_TIME_Relative timeout, | ||
715 | GNUNET_CLIENT_ShutdownTask cont, | ||
716 | void *cont_cls) | ||
583 | { | 717 | { |
718 | struct ShutdownContext *shutdown_ctx; | ||
719 | shutdown_ctx = GNUNET_malloc(sizeof(struct ShutdownContext)); | ||
720 | shutdown_ctx->sched = sched; | ||
721 | shutdown_ctx->cont = cont; | ||
722 | shutdown_ctx->cont_cls = cont_cls; | ||
723 | shutdown_ctx->sock = sock; | ||
724 | shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute(timeout); | ||
725 | |||
584 | GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | 726 | GNUNET_CONNECTION_notify_transmit_ready (sock->sock, |
585 | sizeof (struct | 727 | sizeof (struct |
586 | GNUNET_MessageHeader), | 728 | GNUNET_MessageHeader), |
587 | GNUNET_TIME_UNIT_FOREVER_REL, | 729 | timeout, |
588 | &write_shutdown, sock); | 730 | &write_shutdown, shutdown_ctx); |
589 | } | 731 | } |
590 | 732 | ||
591 | 733 | ||
diff --git a/src/util/connection.c b/src/util/connection.c index 22a75691b..4a54aed1d 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -279,8 +279,27 @@ struct GNUNET_CONNECTION_Handle | |||
279 | */ | 279 | */ |
280 | uint16_t port; | 280 | uint16_t port; |
281 | 281 | ||
282 | /** | ||
283 | * When shutdown, do not ever actually close the socket, but | ||
284 | * free resources. Only should ever be set if using program | ||
285 | * termination as a signal (because only then will the leaked | ||
286 | * socket be freed!) | ||
287 | */ | ||
288 | int persist; | ||
289 | |||
282 | }; | 290 | }; |
283 | 291 | ||
292 | /** | ||
293 | * Set the persist option on this connection handle. Indicates | ||
294 | * that the underlying socket or fd should never really be closed. | ||
295 | * Used for indicating process death. | ||
296 | * | ||
297 | * @param sock the connection to set persistent | ||
298 | */ | ||
299 | void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock) | ||
300 | { | ||
301 | sock->persist = GNUNET_YES; | ||
302 | } | ||
284 | 303 | ||
285 | /** | 304 | /** |
286 | * Create a socket handle by boxing an existing OS socket. The OS | 305 | * Create a socket handle by boxing an existing OS socket. The OS |
@@ -486,7 +505,8 @@ destroy_continuation (void *cls, | |||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 505 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
487 | "Shutting down socket (%p)\n", sock); | 506 | "Shutting down socket (%p)\n", sock); |
488 | #endif | 507 | #endif |
489 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); | 508 | if (sock->persist != GNUNET_YES) |
509 | GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR); | ||
490 | } | 510 | } |
491 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) | 511 | if (sock->read_task != GNUNET_SCHEDULER_NO_TASK) |
492 | { | 512 | { |
@@ -518,8 +538,10 @@ destroy_continuation (void *cls, | |||
518 | sock->nth.notify_ready = NULL; | 538 | sock->nth.notify_ready = NULL; |
519 | notify (sock->nth.notify_ready_cls, 0, NULL); | 539 | notify (sock->nth.notify_ready_cls, 0, NULL); |
520 | } | 540 | } |
521 | if (sock->sock != NULL) | 541 | |
542 | if ((sock->sock != NULL) && (sock->persist != GNUNET_YES)) | ||
522 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); | 543 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock->sock)); |
544 | |||
523 | GNUNET_free_non_null (sock->addr); | 545 | GNUNET_free_non_null (sock->addr); |
524 | GNUNET_free_non_null (sock->hostname); | 546 | GNUNET_free_non_null (sock->hostname); |
525 | #if DEBUG_CONNECTION | 547 | #if DEBUG_CONNECTION |
diff --git a/src/util/server.c b/src/util/server.c index 1353d4c05..e34897f76 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -269,6 +269,13 @@ struct GNUNET_SERVER_Client | |||
269 | * Are we currently trying to receive? | 269 | * Are we currently trying to receive? |
270 | */ | 270 | */ |
271 | int receive_pending; | 271 | int receive_pending; |
272 | |||
273 | /** | ||
274 | * Persist the file handle for this client no matter what happens, | ||
275 | * force the OS to close once the process actually dies. Should only | ||
276 | * be used in special cases! | ||
277 | */ | ||
278 | int persist; | ||
272 | }; | 279 | }; |
273 | 280 | ||
274 | 281 | ||
@@ -933,11 +940,16 @@ sock_check (void *cls) | |||
933 | * Destroy this socket (free resources). | 940 | * Destroy this socket (free resources). |
934 | * | 941 | * |
935 | * @param cls the socket | 942 | * @param cls the socket |
943 | * @param persist set the socket to be persisted | ||
936 | */ | 944 | */ |
937 | static void | 945 | static void |
938 | sock_destroy (void *cls) | 946 | sock_destroy (void *cls, int persist) |
939 | { | 947 | { |
940 | GNUNET_CONNECTION_destroy (cls, GNUNET_NO); | 948 | struct GNUNET_CONNECTION_Handle *sock = cls; |
949 | if (persist == GNUNET_YES) | ||
950 | GNUNET_CONNECTION_persist_ (sock); | ||
951 | |||
952 | GNUNET_CONNECTION_destroy (sock, GNUNET_NO); | ||
941 | } | 953 | } |
942 | 954 | ||
943 | 955 | ||
@@ -1168,6 +1180,7 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1168 | client->receive_cancel (client->client_closure); | 1180 | client->receive_cancel (client->client_closure); |
1169 | client->receive_pending = GNUNET_NO; | 1181 | client->receive_pending = GNUNET_NO; |
1170 | } | 1182 | } |
1183 | |||
1171 | rc = client->reference_count; | 1184 | rc = client->reference_count; |
1172 | if (client->server != NULL) | 1185 | if (client->server != NULL) |
1173 | { | 1186 | { |
@@ -1200,7 +1213,7 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1200 | return; | 1213 | return; |
1201 | if (client->in_process_client_buffer == GNUNET_YES) | 1214 | if (client->in_process_client_buffer == GNUNET_YES) |
1202 | return; | 1215 | return; |
1203 | client->destroy (client->client_closure); | 1216 | client->destroy (client->client_closure, client->persist); |
1204 | GNUNET_free (client); | 1217 | GNUNET_free (client); |
1205 | } | 1218 | } |
1206 | 1219 | ||
@@ -1232,6 +1245,17 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, | |||
1232 | timeout, callback, callback_cls); | 1245 | timeout, callback, callback_cls); |
1233 | } | 1246 | } |
1234 | 1247 | ||
1248 | /** | ||
1249 | * Set the persistent flag on this client, used to setup client connection | ||
1250 | * to only be killed when the service it's connected to is actually dead. | ||
1251 | * | ||
1252 | * @param client the client to set the persistent flag on | ||
1253 | */ | ||
1254 | void | ||
1255 | GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client) | ||
1256 | { | ||
1257 | client->persist = GNUNET_YES; | ||
1258 | } | ||
1235 | 1259 | ||
1236 | /** | 1260 | /** |
1237 | * Resume receiving from this client, we are done processing the | 1261 | * Resume receiving from this client, we are done processing the |
diff --git a/src/util/service.c b/src/util/service.c index e6fec7514..8597fddf6 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -570,6 +570,45 @@ handle_test (void *cls, | |||
570 | } | 570 | } |
571 | 571 | ||
572 | 572 | ||
573 | static size_t | ||
574 | transmit_shutdown_deny (void *cls, size_t size, void *buf) | ||
575 | { | ||
576 | struct GNUNET_SERVER_Client *client = cls; | ||
577 | struct GNUNET_MessageHeader *msg; | ||
578 | |||
579 | if (size < sizeof (struct GNUNET_MessageHeader)) | ||
580 | { | ||
581 | return 0; /* client disconnected */ | ||
582 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
583 | } | ||
584 | msg = (struct GNUNET_MessageHeader *) buf; | ||
585 | msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN_REFUSE); | ||
586 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
587 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
588 | GNUNET_SERVER_client_drop(client); | ||
589 | return sizeof (struct GNUNET_MessageHeader); | ||
590 | } | ||
591 | |||
592 | static size_t | ||
593 | transmit_shutdown_ack (void *cls, size_t size, void *buf) | ||
594 | { | ||
595 | struct GNUNET_SERVER_Client *client = cls; | ||
596 | struct GNUNET_MessageHeader *msg; | ||
597 | |||
598 | if (size < sizeof (struct GNUNET_MessageHeader)) | ||
599 | { | ||
600 | return 0; /* client disconnected */ | ||
601 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
602 | } | ||
603 | |||
604 | msg = (struct GNUNET_MessageHeader *) buf; | ||
605 | msg->type = htons (GNUNET_MESSAGE_TYPE_SHUTDOWN_ACK); | ||
606 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
607 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
608 | GNUNET_SERVER_client_drop(client); | ||
609 | return sizeof (struct GNUNET_MessageHeader); | ||
610 | } | ||
611 | |||
573 | /** | 612 | /** |
574 | * Handler for SHUTDOWN message. | 613 | * Handler for SHUTDOWN message. |
575 | * | 614 | * |
@@ -583,19 +622,31 @@ handle_shutdown (void *cls, | |||
583 | const struct GNUNET_MessageHeader *message) | 622 | const struct GNUNET_MessageHeader *message) |
584 | { | 623 | { |
585 | struct GNUNET_SERVICE_Context *service = cls; | 624 | struct GNUNET_SERVICE_Context *service = cls; |
625 | |||
626 | /* FIXME: why is this call necessary???? */ | ||
627 | GNUNET_SERVER_client_keep(client); | ||
586 | if (!service->allow_shutdown) | 628 | if (!service->allow_shutdown) |
587 | { | 629 | { |
588 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 630 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
589 | _ | 631 | _ |
590 | ("Received shutdown request, but configured to ignore!\n")); | 632 | ("Received shutdown request, but configured to ignore!\n")); |
591 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 633 | GNUNET_SERVER_notify_transmit_ready (client, |
634 | sizeof(struct GNUNET_MessageHeader), | ||
635 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
636 | &transmit_shutdown_deny, client); | ||
592 | return; | 637 | return; |
593 | } | 638 | } |
594 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 639 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
595 | _("Initiating shutdown as requested by client.\n")); | 640 | _("Initiating shutdown as requested by client.\n")); |
641 | |||
642 | GNUNET_SERVER_notify_transmit_ready (client, | ||
643 | sizeof(struct GNUNET_MessageHeader), | ||
644 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
645 | &transmit_shutdown_ack, client); | ||
646 | |||
596 | GNUNET_assert (service->sched != NULL); | 647 | GNUNET_assert (service->sched != NULL); |
648 | GNUNET_SERVER_client_persist_ (client); | ||
597 | GNUNET_SCHEDULER_shutdown (service->sched); | 649 | GNUNET_SCHEDULER_shutdown (service->sched); |
598 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
599 | } | 650 | } |
600 | 651 | ||
601 | 652 | ||
diff --git a/src/util/test_server.c b/src/util/test_server.c index 901b78a08..5d714d6f9 100644 --- a/src/util/test_server.c +++ b/src/util/test_server.c | |||
@@ -152,7 +152,7 @@ my_check (void *cls) | |||
152 | } | 152 | } |
153 | 153 | ||
154 | 154 | ||
155 | static void my_destroy (void *cls); | 155 | static void my_destroy (void *cls, int persist); |
156 | 156 | ||
157 | 157 | ||
158 | struct CopyContext | 158 | struct CopyContext |
@@ -217,7 +217,7 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = { | |||
217 | 217 | ||
218 | 218 | ||
219 | static void | 219 | static void |
220 | my_destroy (void *cls) | 220 | my_destroy (void *cls, int persist) |
221 | { | 221 | { |
222 | int *ok = cls; | 222 | int *ok = cls; |
223 | GNUNET_assert (5 == *ok); | 223 | GNUNET_assert (5 == *ok); |
diff --git a/src/util/test_service.c b/src/util/test_service.c index a40630c64..544f86fba 100644 --- a/src/util/test_service.c +++ b/src/util/test_service.c | |||
@@ -43,6 +43,16 @@ static struct GNUNET_SERVICE_Context *sctx; | |||
43 | 43 | ||
44 | static int ok = 1; | 44 | static int ok = 1; |
45 | 45 | ||
46 | void | ||
47 | end_cont (void *cls, | ||
48 | int reason) | ||
49 | { | ||
50 | if (sctx != NULL) | ||
51 | GNUNET_SERVICE_stop (sctx); | ||
52 | else | ||
53 | GNUNET_SCHEDULER_shutdown (sched); | ||
54 | ok = 0; | ||
55 | } | ||
46 | 56 | ||
47 | static void | 57 | static void |
48 | end_it (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 58 | end_it (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
@@ -50,12 +60,7 @@ end_it (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
50 | struct GNUNET_CLIENT_Connection *client = cls; | 60 | struct GNUNET_CLIENT_Connection *client = cls; |
51 | 61 | ||
52 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down service\n"); | 62 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down service\n"); |
53 | GNUNET_CLIENT_service_shutdown (client); | 63 | GNUNET_CLIENT_service_shutdown (sched, client, GNUNET_TIME_UNIT_FOREVER_REL, &end_cont, NULL); |
54 | if (sctx != NULL) | ||
55 | GNUNET_SERVICE_stop (sctx); | ||
56 | else | ||
57 | GNUNET_SCHEDULER_shutdown (sched); | ||
58 | ok = 0; | ||
59 | } | 64 | } |
60 | 65 | ||
61 | 66 | ||