+/**
+ * Cleanup the context information created for managing a peer's service
+ *
+ * @param mctx the ManageServiceContext
+ */
+static void
+cleanup_mctx (struct ManageServiceContext *mctx)
+{
+ mctx->expired = GNUNET_YES;
+ GNUNET_CONTAINER_DLL_remove (mctx_head,
+ mctx_tail,
+ mctx);
+ GNUNET_ARM_disconnect (mctx->ah);
+ GNUNET_assert (0 < mctx->peer->reference_cnt);
+ mctx->peer->reference_cnt--;
+ if ((GNUNET_YES == mctx->peer->destroy_flag) &&
+ (0 == mctx->peer->reference_cnt))
+ GST_destroy_peer (mctx->peer);
+ GNUNET_free (mctx->service);
+ GNUNET_free (mctx);
+}
+
+
+/**
+ * Stops a peer
+ *
+ * @param peer the peer to stop
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static int
+stop_peer (struct Peer *peer)
+{
+ GNUNET_assert (GNUNET_NO == peer->is_remote);
+ if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
+ return GNUNET_SYSERR;
+ peer->details.local.is_running = GNUNET_NO;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Cleans up the given PeerReconfigureContext
+ *
+ * @param prc the PeerReconfigureContext
+ */
+static void
+cleanup_prc (struct PeerReconfigureContext *prc)
+{
+ struct Peer *peer;
+
+ if (VALID_PEER_ID (prc->peer_id))
+ {
+ peer = GST_peer_list [prc->peer_id];
+ if (1 != prc->stopped)
+ {
+ GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
+ stop_peer (peer); /* Stop the peer synchronously */
+ }
+ }
+ if (NULL != prc->cfg)
+ GNUNET_CONFIGURATION_destroy (prc->cfg);
+ GNUNET_CONTAINER_DLL_remove (prc_head,
+ prc_tail,
+ prc);
+ GNUNET_free (prc);
+}
+
+
+/**
+ * Notify peers subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client)
+{
+ struct ForwardedOperationContext *fopc;
+ struct ForwardedOperationContext *fopcn;
+ struct ManageServiceContext *mctx;
+ struct ManageServiceContext *mctxn;
+ struct PeerReconfigureContext *prc;
+ struct PeerReconfigureContext *prcn;
+
+ for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
+ {
+ fopcn = fopc->next;
+ if (client == fopc->client)
+ {
+ if (OP_PEER_CREATE == fopc->type)
+ GNUNET_free (fopc->cls);
+ GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+ GST_forwarded_operation_timeout (fopc);
+ }
+ }
+ for (mctx = mctx_head; NULL != mctx; mctx = mctxn)
+ {
+ mctxn = mctx->next;
+ if (client == mctx->client)
+ cleanup_mctx (mctx);
+ }
+ for (prc = prc_head; NULL != prc; prc = prcn)
+ {
+ prcn = prc->next;
+ if (client == prc->client)
+ cleanup_prc (prc);
+ }
+}
+
+