aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rps/gnunet-service-rps.c55
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;
304static struct GNUNET_CADET_Handle *cadet_handle; 311static 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 */
890static void
891destroy_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 */
908static void
909schedule_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);