+/**
+ * Check if any of the clients we have left are unrelated to
+ * monitoring.
+ *
+ * @param sh service to check clients for
+ * @return #GNUNET_YES if we have non-monitoring clients left
+ */
+static int
+have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
+{
+ struct GNUNET_SERVICE_Client *client;
+
+ for (client = sh->clients_head;NULL != client; client = client->next)
+ {
+ if (client->is_monitor)
+ continue;
+ return GNUNET_YES;
+ }
+ return GNUNET_NO;
+}
+
+
+/**
+ * Shutdown task triggered when a service should be terminated.
+ * This considers active clients and the service options to see
+ * how this specific service is to be terminated, and depending
+ * on this proceeds with the shutdown logic.
+ *
+ * @param cls our `struct GNUNET_SERVICE_Handle`
+ */
+static void
+service_main (void *cls)
+{
+ struct GNUNET_SERVICE_Handle *sh = cls;
+ struct GNUNET_SERVICE_Client *client;
+ int alive;
+
+ switch (sh->options)
+ {
+ case GNUNET_SERVICE_OPTION_NONE:
+ GNUNET_SERVICE_shutdown (sh);
+ break;
+ case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
+ /* This task should never be run if we are using
+ the manual shutdown. */
+ GNUNET_assert (0);
+ break;
+ case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
+ sh->got_shutdown = GNUNET_YES;
+ GNUNET_SERVICE_suspend (sh);
+ if (GNUNET_NO == have_non_monitor_clients (sh))
+ GNUNET_SERVICE_shutdown (sh);
+ break;
+ }
+}
+
+
+/**
+ * First task run by any service. Initializes our shutdown task,
+ * starts the listening operation on our listen sockets and launches
+ * the custom logic of the application service.
+ *
+ * @param cls our `struct GNUNET_SERVICE_Handle`
+ */