diff options
author | Julius Bünger <buenger@mytum.de> | 2018-08-13 17:32:58 +0200 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2018-08-13 17:32:58 +0200 |
commit | 3318097204119e550a5e9691d7c3f11ea64fc8a8 (patch) | |
tree | 088a753f3a98a875e5f8e55dece8d57aaeef9fca | |
parent | 32a0ea5a355f8ce1166376b9cb9b2d023f082400 (diff) | |
download | gnunet-3318097204119e550a5e9691d7c3f11ea64fc8a8.tar.gz gnunet-3318097204119e550a5e9691d7c3f11ea64fc8a8.zip |
Schedule destruction of channel during destruction of other channel
-rw-r--r-- | src/rps/gnunet-service-rps.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 18b9b792b..e0301af6b 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c | |||
@@ -275,6 +275,13 @@ struct ChannelCtx | |||
275 | * @brief The peer context associated with the channel | 275 | * @brief The peer context associated with the channel |
276 | */ | 276 | */ |
277 | struct PeerContext *peer_ctx; | 277 | struct PeerContext *peer_ctx; |
278 | |||
279 | /** | ||
280 | * @brief When channel destruction needs to be delayed (because it is called | ||
281 | * from within the cadet routine of another channel destruction) this task | ||
282 | * refers to the respective _SCHEDULER_Task. | ||
283 | */ | ||
284 | struct GNUNET_SCHEDULER_Task *destruction_task; | ||
278 | }; | 285 | }; |
279 | 286 | ||
280 | /** | 287 | /** |
@@ -304,7 +311,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *peer_map; | |||
304 | static struct GNUNET_CADET_Handle *cadet_handle; | 311 | static struct GNUNET_CADET_Handle *cadet_handle; |
305 | 312 | ||
306 | 313 | ||
307 | |||
308 | /** | 314 | /** |
309 | * @brief Get the #PeerContext associated with a peer | 315 | * @brief Get the #PeerContext associated with a peer |
310 | * | 316 | * |
@@ -864,13 +870,47 @@ destroy_channel (struct ChannelCtx *channel_ctx) | |||
864 | { | 870 | { |
865 | struct PeerContext *peer_ctx = channel_ctx->peer_ctx; | 871 | struct PeerContext *peer_ctx = channel_ctx->peer_ctx; |
866 | 872 | ||
867 | GNUNET_assert (channel_ctx == peer_ctx->send_channel_ctx || | 873 | if (NULL != channel_ctx->destruction_task) |
868 | channel_ctx == peer_ctx->recv_channel_ctx); | 874 | { |
869 | 875 | GNUNET_SCHEDULER_cancel (channel_ctx->destruction_task); | |
876 | channel_ctx->destruction_task = NULL; | ||
877 | } | ||
870 | GNUNET_CADET_channel_destroy (channel_ctx->channel); | 878 | GNUNET_CADET_channel_destroy (channel_ctx->channel); |
879 | channel_ctx->channel = NULL; | ||
871 | remove_channel_ctx (channel_ctx); | 880 | remove_channel_ctx (channel_ctx); |
872 | } | 881 | } |
873 | 882 | ||
883 | /** | ||
884 | * @brief Destroy a cadet channel. | ||
885 | * | ||
886 | * This satisfies the function signature of #GNUNET_SCHEDULER_TaskCallback. | ||
887 | * | ||
888 | * @param cls | ||
889 | */ | ||
890 | static void | ||
891 | destroy_channel_cb (void *cls) | ||
892 | { | ||
893 | struct ChannelCtx *channel_ctx = cls; | ||
894 | channel_ctx->destruction_task = NULL; | ||
895 | destroy_channel (channel_ctx); | ||
896 | } | ||
897 | |||
898 | /** | ||
899 | * @brief Schedule the destruction of a channel for immediately afterwards. | ||
900 | * | ||
901 | * In case a channel is to be destroyed from within the callback to the | ||
902 | * destruction of another channel (send channel), we cannot call | ||
903 | * GNUNET_CADET_channel_destroy directly, but need to use this scheduling | ||
904 | * construction. | ||
905 | * | ||
906 | * @param channel_ctx channel to be destroyed. | ||
907 | */ | ||
908 | static void | ||
909 | schedule_channel_destruction (struct ChannelCtx *channel_ctx) | ||
910 | { | ||
911 | channel_ctx->destruction_task = | ||
912 | GNUNET_SCHEDULER_add_now (destroy_channel_cb, channel_ctx); | ||
913 | } | ||
874 | 914 | ||
875 | /** | 915 | /** |
876 | * @brief Remove peer | 916 | * @brief Remove peer |
@@ -937,11 +977,13 @@ destroy_peer (struct PeerContext *peer_ctx) | |||
937 | 977 | ||
938 | if (NULL != peer_ctx->send_channel_ctx) | 978 | if (NULL != peer_ctx->send_channel_ctx) |
939 | { | 979 | { |
940 | destroy_channel (peer_ctx->send_channel_ctx); | 980 | /* This is possibly called from within channel destruction */ |
981 | schedule_channel_destruction (peer_ctx->send_channel_ctx); | ||
941 | } | 982 | } |
942 | if (NULL != peer_ctx->recv_channel_ctx) | 983 | if (NULL != peer_ctx->recv_channel_ctx) |
943 | { | 984 | { |
944 | destroy_channel (peer_ctx->recv_channel_ctx); | 985 | /* This is possibly called from within channel destruction */ |
986 | schedule_channel_destruction (peer_ctx->recv_channel_ctx); | ||
945 | } | 987 | } |
946 | 988 | ||
947 | if (GNUNET_YES != | 989 | if (GNUNET_YES != |
@@ -3874,6 +3916,7 @@ shutdown_task (void *cls) | |||
3874 | RPS_sampler_destroy (client_sampler); | 3916 | RPS_sampler_destroy (client_sampler); |
3875 | GNUNET_CADET_close_port (cadet_port); | 3917 | GNUNET_CADET_close_port (cadet_port); |
3876 | GNUNET_CADET_disconnect (cadet_handle); | 3918 | GNUNET_CADET_disconnect (cadet_handle); |
3919 | cadet_handle = NULL; | ||
3877 | View_destroy (); | 3920 | View_destroy (); |
3878 | CustomPeerMap_destroy (push_map); | 3921 | CustomPeerMap_destroy (push_map); |
3879 | CustomPeerMap_destroy (pull_map); | 3922 | CustomPeerMap_destroy (pull_map); |