misc. bugfixes and API improvements
authorChristian Grothoff <christian@grothoff.org>
Sun, 8 Nov 2009 17:17:33 +0000 (17:17 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sun, 8 Nov 2009 17:17:33 +0000 (17:17 +0000)
27 files changed:
src/arm/arm_api.c
src/arm/gnunet-service-arm.c
src/arm/test_gnunet_arm.sh
src/core/gnunet-service-core.c
src/datastore/gnunet-service-datastore.c
src/fs/gnunet-service-fs.c
src/fs/test_fs_search_data.conf
src/include/gnunet_service_lib.h
src/peerinfo/gnunet-service-peerinfo.c
src/statistics/gnunet-service-statistics.c
src/template/gnunet-service-template.c
src/testing/test_testing_connect.c
src/testing/test_testing_connect_peer1.conf
src/testing/test_testing_connect_peer2.conf
src/testing/testing.c
src/topology/test_gnunet_service_topology.c
src/transport/gnunet-service-transport.c
src/util/client.c
src/util/connection.c
src/util/gnunet-service-resolver.c
src/util/scheduler.c
src/util/server.c
src/util/service.c
src/util/test_container_heap.c
src/util/test_server_disconnect.c
src/util/test_server_with_client.c
src/util/test_service.c

index f2d2b293a76b03375a5ba8c0ba65c349ad57ba9b..bc80b779f32957318d0df8d9d0c9551db9884c49 100644 (file)
@@ -163,12 +163,22 @@ arm_service_report (void *cls,
 
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
     {
+#if DEBUG_ARM
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Looks like `%s' is already running.\n",
+                 "gnunet-service-arm");
+#endif
       /* arm is running! */
       if (pos->callback != NULL)
         pos->callback (pos->cls, GNUNET_YES);
       GNUNET_free (pos);
       return;
     }
+#if DEBUG_ARM
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Looks like `%s' is not running, will start it.\n",
+             "gnunet-service-arm");
+#endif
   /* FIXME: should we check that HOSTNAME for 'arm' is localhost? */
   /* start service */
   if (GNUNET_OK !=
@@ -236,7 +246,10 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
   if (msg == NULL)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("Error receiving response from ARM service\n"));
+                  _("Error receiving response to `%s' request from ARM service\n"),
+                 (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) 
+                 ? "START"
+                 : "STOP");
       GNUNET_CLIENT_disconnect (sc->h->client);
       sc->h->client = GNUNET_CLIENT_connect (sc->h->sched, 
                                             "arm", 
@@ -304,7 +317,10 @@ change_service (struct GNUNET_ARM_Handle *h,
     }
 #if DEBUG_ARM
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              _("ARM requests starting of service `%s'.\n"), service_name);
+              (type == GNUNET_MESSAGE_TYPE_ARM_START) 
+             ? _("Requesting start of service `%s'.\n") 
+             : _("Requesting termination of service `%s'.\n"),
+             service_name);
 #endif
   sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen);
   sctx->h = h;
@@ -355,7 +371,7 @@ GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h,
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Starting service `%s'\n"), service_name);
-  if (0 == strcmp ("arm", service_name))
+  if (0 == strcasecmp ("arm", service_name))
     {
       sctx = GNUNET_malloc (sizeof (struct RequestContext));
       sctx->h = h;
@@ -388,7 +404,7 @@ GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h,
 {
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Stopping service `%s'\n"), service_name);
-  if (0 == strcmp ("arm", service_name))
+  if (0 == strcasecmp ("arm", service_name))
     {
       GNUNET_CLIENT_service_shutdown (h->client);
       h->client = NULL;
index f907d944fefec3cc9a2cde5e5e664a7b0c57cf5c..4a30848eb16009f62ac9978e5a789b051fcfe51c 100644 (file)
@@ -157,6 +157,17 @@ static char *prefix_command;
  */
 static int in_shutdown;
 
+/**
+ * Handle to our server instance.  Our server is a bit special in that
+ * its service is not immediately stopped once we get a shutdown
+ * request (since we need to continue service until all of our child
+ * processes are dead).  This handle is used to shut down the server
+ * (and thus trigger process termination) once all child processes are
+ * also dead.  A special option in the ARM configuration modifies the
+ * behaviour of the service implementation to not do the shutdown
+ * immediately.
+ */
+static struct GNUNET_SERVER_Handle *server;
 
 /**
  * Background task doing maintenance.
@@ -646,9 +657,16 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       pos = running;
       while (NULL != pos)
         {
-         if ( (pos->pid != 0) &&
-              (0 != PLIBC_KILL (pos->pid, SIGTERM)) )
-           GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");        
+         if (pos->pid != 0) 
+           {
+#if DEBUG_ARM
+             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+                         "Sending SIGTERM to `%s'\n",
+                         pos->name);
+#endif
+             if (0 != PLIBC_KILL (pos->pid, SIGTERM))
+               GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");            
+           }
           pos = pos->next;
         }
     }
@@ -656,7 +674,14 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     {
       if ( (in_shutdown == GNUNET_YES) &&
           (running == NULL) )
-       return; /* we are done! */      
+       {
+#if DEBUG_ARM
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+                     "ARM service terminates.\n");
+#endif 
+         GNUNET_SERVER_destroy (server);
+         return; /* we are done! */      
+       }
       GNUNET_SCHEDULER_add_delayed (tc->sched,
                                    (in_shutdown == GNUNET_YES)
                                    ? MAINT_FAST_FREQUENCY
@@ -716,6 +741,12 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                    _("Service `%s' terminated with status %s/%d, will try to restart it!\n"),
                    pos->name, statstr, statcode);
+#if DEBUG_ARM
+      else
+       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+                   "Service `%s' terminated with status %s/%d\n",
+                   pos->name, statstr, statcode);
+#endif 
       /* schedule restart */
       pos->pid = 0;
       prev = pos;
@@ -762,20 +793,22 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = {
  *
  * @param cls closure
  * @param s scheduler to use
- * @param server the initialized server
+ * @param serv the initialized server
  * @param c configuration to use
  */
 static void
 run (void *cls,
      struct GNUNET_SCHEDULER_Handle *s,
-     struct GNUNET_SERVER_Handle *server,
+     struct GNUNET_SERVER_Handle *serv,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
   char *defaultservices;
   char *pos;
 
+  GNUNET_assert (serv != NULL);
   cfg = c;
   sched = s;
+  server = serv;
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg,
                                              "ARM",
@@ -831,7 +864,9 @@ main (int argc, char *const *argv)
 {
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
-                              argv, "arm", &run, NULL)) ? 0 : 1;
+                              argv, "arm",
+                             GNUNET_YES,
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-arm.c */
index d36c2ca38180271337c30d28650e1a376a2d8946..4c3edb24972df1e99a6c3a3246627ac42349de4b 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-exe="./gnunet-arm -c test_arm_api_data.conf"
+exe="valgrind --trace-children=yes ./gnunet-arm -c test_arm_api_data.conf"
 out=`mktemp /tmp/test-gnunet-arm-logXXXXXXXX`
 #DEBUG="-L DEBUG"
 
index 839eb2727f3502fdd180670bcb47a43aaf6b7472..9d9ba56903fef3fe1e145d74ca6894d6f02b007f 100644 (file)
@@ -3214,7 +3214,9 @@ main (int argc, char *const *argv)
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
                               argv,
-                              "core", &run, NULL)) ? 0 : 1;
+                              "core",
+                             GNUNET_SERVICE_OPTION_NONE,
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-core.c */
index 27b1cd58e2ec7420eb82498645205a61bbed52d6..d58f0f8d9d7fdafa7784dd55d24407c04c48d41a 100644 (file)
@@ -1341,7 +1341,9 @@ main (int argc, char *const *argv)
   ret = (GNUNET_OK ==
          GNUNET_SERVICE_run (argc,
                              argv,
-                             "datastore", &run, NULL)) ? 0 : 1;
+                             "datastore",
+                            GNUNET_SERVICE_OPTION_NONE,
+                            &run, NULL)) ? 0 : 1;
   return ret;
 }
 
index 0e592e094a201a3b4acd1c58462c6ccd5d64ebca..bec69f6ecf3550ebd6f1dbf07053e0f73f87e262 100644 (file)
@@ -3358,7 +3358,9 @@ main (int argc, char *const *argv)
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
                               argv,
-                              "fs", &run, NULL)) ? 0 : 1;
+                              "fs",
+                             GNUNET_SERVICE_OPTION_NONE,
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-fs.c */
index fd82a15fca5a9f1e44c1a3b8a66308ac5220a028..cffe83f57e184438d2de826fa94f5d3e9d94c787 100644 (file)
@@ -1,6 +1,6 @@
 [PATHS]
 SERVICEHOME = /tmp/gnunet-test-fs-search/
-DEFAULTCONFIG = test_fs_download_data.conf
+DEFAULTCONFIG = test_fs_search_data.conf
 
 [gnunetd]
 HOSTKEY = $SERVICEHOME/.hostkey
index 82089954edb497c78a6055d0edfcc93f6d1dfeee..66e4f0cd961f77afad2e1fd490e513241b0a942f 100644 (file)
@@ -54,6 +54,24 @@ typedef void (*GNUNET_SERVICE_Main) (void *cls,
                                      cfg);
 
 
+/**
+ * Options for the service (bitmask).
+ */
+enum GNUNET_SERVICE_Options
+  {
+    /**
+     * Use defaults.
+     */
+    GNUNET_SERVICE_OPTION_NONE = 0,
+
+    /**
+     * Do not trigger server shutdown on signals, allow for the user
+     * to terminate the server explicitly when needed.
+     */
+    GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN = 1
+  };
+
+
 /**
  * Run a standard GNUnet service startup sequence (initialize loggers
  * and configuration, parse options).
@@ -61,6 +79,7 @@ typedef void (*GNUNET_SERVICE_Main) (void *cls,
  * @param argc number of command line arguments
  * @param argv command line arguments
  * @param serviceName our service name
+ * @param opt service options
  * @param task main task of the service
  * @param task_cls closure for task
  * @return GNUNET_SYSERR on error, GNUNET_OK
@@ -69,6 +88,7 @@ typedef void (*GNUNET_SERVICE_Main) (void *cls,
 int GNUNET_SERVICE_run (int argc,
                         char *const *argv,
                         const char *serviceName,
+                       enum GNUNET_SERVICE_Options opt,
                         GNUNET_SERVICE_Main task,
                         void *task_cls);
 
index f5a60470e136ff4f43a5601bed15df36b18d57dd..ee12878310784a6b45427c0ff0d115bc44c47cca 100644 (file)
@@ -711,7 +711,9 @@ main (int argc, char *const *argv)
   ret = (GNUNET_OK ==
         GNUNET_SERVICE_run (argc,
                             argv,
-                              "peerinfo", &run, NULL)) ? 0 : 1;
+                              "peerinfo",
+                            GNUNET_SERVICE_OPTION_NONE,
+                            &run, NULL)) ? 0 : 1;
   GNUNET_free_non_null (networkIdDirectory);
   GNUNET_free_non_null (trustDirectory);
   return ret;
index 8de9a8047df7596e1428c896ac050109fc5d952b..c90038e03a88809d9eeb722ad90be2372ba825b3 100644 (file)
@@ -486,7 +486,9 @@ main (int argc, char *const *argv)
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
                               argv,
-                              "statistics", &run, NULL)) ? 0 : 1;
+                              "statistics",
+                             GNUNET_SERVICE_OPTION_NONE,
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-statistics.c */
index 15ba94b7dfa5cda136a455e71fa6040d7fd04c68..39d332226c902b98ddbe6f7813303165f76f3aa3 100644 (file)
@@ -88,7 +88,9 @@ main (int argc, char *const *argv)
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
                               argv,
-                              "template", &run, NULL)) ? 0 : 1;
+                              "template",
+                             GNUNET_SERVICE_OPTION_NONE,
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-template.c */
index 431b63963fd2f3a00a2826ab2dc794d5f73de2d4..ade3fed11eb524f9568588289d57655e9005e11e 100644 (file)
@@ -24,7 +24,7 @@
 #include "platform.h"
 #include "gnunet_testing_lib.h"
 
-#define VERBOSE GNUNET_NO
+#define VERBOSE GNUNET_YES
 
 
 /**
@@ -51,7 +51,7 @@ static void end2_cb(void *cls,
   GNUNET_assert (emsg == NULL); 
 #if VERBOSE
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Daemon terminated, will now exit.\n");
+             "Both daemons terminated, will now exit.\n");
 #endif
  ok = 0;
 }
index 020504728415af1d854168a83748e1e0cc54bfe7..32ddbfc4ddf61678ba188b350647bb5b261bf776 100644 (file)
@@ -17,6 +17,7 @@ PLUGINS = tcp
 PORT = 12566
 HOSTNAME = localhost
 DEFAULTSERVICES = peerinfo transport core
+DEBUG = YES
 
 [statistics]
 PORT = 12567
@@ -32,6 +33,7 @@ HOSTNAME = localhost
 [core]
 PORT = 12570
 HOSTNAME = localhost
+DEBUG = YES
 
 [testing]
 WEAKRANDOM = YES
index 196e96a845e223d268fd80ccb858e2bfada9130b..a152ff237a032f40ebcf1be5eef54feefd9e0d14 100644 (file)
@@ -17,6 +17,7 @@ PLUGINS = tcp
 PORT = 22566
 DEFAULTSERVICES = peerinfo transport core
 HOSTNAME = localhost
+DEBUG = YES
 
 [statistics]
 PORT = 22567
@@ -32,6 +33,7 @@ HOSTNAME = localhost
 [core]
 PORT = 22570
 HOSTNAME = localhost
+DEBUG = YES
 
 [testing]
 WEAKRANDOM = YES
index e34e7a9ac905f67f634b0d93f48314cd3bb9fa48..6edefb14a64a21633dd8419a334c535442a85ed3 100644 (file)
 #include "gnunet_testing_lib.h"
 #include "gnunet_transport_service.h"
 
-#define DEBUG_TESTING GNUNET_NO
+#define DEBUG_TESTING GNUNET_YES
 
 /**
  * How long do we wait after starting gnunet-service-arm
  * for the core service to be alive?
  */
-#define ARM_START_WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+#define ARM_START_WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
 
 /**
  * How many times are we willing to try to wait for "scp" or
@@ -236,6 +236,7 @@ testing_init (void *cls,
   d->cb = NULL;
   if (server == NULL)
     {
+      d->server = NULL;
       if (GNUNET_YES == d->dead)
        GNUNET_TESTING_daemon_stop (d, d->dead_cb, d->dead_cb_cls);
       else if (NULL != cb)
@@ -428,15 +429,15 @@ start_fsm (void *cls,
                  "gnunet-service-arm");
 #endif
       d->phase = SP_START_CORE;
-      GNUNET_CORE_connect (d->sched,
-                          d->cfg,
-                          ARM_START_WAIT,
-                          d,
-                          &testing_init,
-                          NULL, NULL, NULL, 
-                          NULL, GNUNET_NO,
-                          NULL, GNUNET_NO,
-                          no_handlers);     
+      d->server = GNUNET_CORE_connect (d->sched,
+                                      d->cfg,
+                                      ARM_START_WAIT,
+                                      d,
+                                      &testing_init,
+                                      NULL, NULL, NULL, 
+                                      NULL, GNUNET_NO,
+                                      NULL, GNUNET_NO,
+                                      no_handlers);     
       break;
     case SP_START_CORE:
       GNUNET_break (0);
index 2536f5454553f9b8e42f3f9119e31a8c79a14f68..130f406295d26cc4d0160432b0eae80bcc69492a 100644 (file)
@@ -66,7 +66,8 @@ notify_connect_complete(void *cls,
     {
       /* FIXME: check that topology adds a few more links
         in addition to those that were seeded */
-      sleep (100);
+      /* For now, sleep so we can have the daemon do some work */
+      sleep (10);
       GNUNET_TESTING_daemons_stop (pg);
       ok = 0;     
     }
index efe53e0215388c90c214f377540e225ca77e5ed1..5c5c64dbcd8db213606a909c609fbb1e48950d25 100644 (file)
@@ -2709,6 +2709,7 @@ main (int argc, char *const *argv)
          GNUNET_SERVICE_run (argc,
                              argv,
                              "transport",
+                             GNUNET_SERVICE_OPTION_NONE,
                              &run, NULL)) ? 0 : 1;
 }
 
index 05f579b9f5791509e6ccb7cde055b60fc7c214c4..664b06271091b10feb7b56441a0762deb4fcfdc7 100644 (file)
@@ -566,7 +566,9 @@ write_test (void *cls, size_t size, void *buf)
       return 0;                 /* client disconnected */
     }
 #if DEBUG_CLIENT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Transmitting TEST request.\n"));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Transmitting `%s' request.\n",
+             "TEST");
 #endif
   msg = (struct GNUNET_MessageHeader *) buf;
   msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
@@ -642,7 +644,6 @@ GNUNET_CLIENT_service_test (struct GNUNET_SCHEDULER_Handle *sched,
 static size_t client_notify (void *cls, size_t size, void *buf);
 
 
-
 /**
  * This task is run if we should re-try connection to the
  * service after a while.
@@ -657,6 +658,16 @@ client_delayed_retry (void *cls,
   struct GNUNET_CLIENT_TransmitHandle *th = cls;
 
   th->task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    {
+#if DEBUG_CLIENT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Transmission failed due to shutdown.\n");
+#endif
+      th->notify (th->notify_cls, 0, NULL);
+      GNUNET_free (th);
+      return;
+    }
   th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock,
                                                     th->size,
                                                     GNUNET_TIME_absolute_get_remaining
@@ -693,11 +704,19 @@ client_notify (void *cls, size_t size, void *buf)
   th->sock->th = NULL;
   if (buf == NULL)
     {
+      // FIXME: need a way to check if the
+      // reason is SHUTDOWN (not timeout) and
+      // if so NOT retry!
       delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
       delay.value /= 2;
       if ((GNUNET_YES != th->auto_retry) ||
           (0 == --th->attempts_left) || (delay.value < 1))
         {
+#if DEBUG_CLIENT
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Transmission failed %u times, giving up.\n",
+                     MAX_ATTEMPTS - th->attempts_left);
+#endif
           GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
           GNUNET_free (th);
           return 0;
@@ -708,6 +727,12 @@ client_notify (void *cls, size_t size, void *buf)
                                    th->sock->service_name, th->sock->cfg);
       GNUNET_assert (NULL != th->sock->sock);
       delay = GNUNET_TIME_relative_min (delay, GNUNET_TIME_UNIT_SECONDS);
+#if DEBUG_CLIENT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Transmission failed %u times, trying again in %llums.\n",
+                 MAX_ATTEMPTS - th->attempts_left,
+                 (unsigned long long) delay.value);
+#endif
       th->task = GNUNET_SCHEDULER_add_delayed (th->sock->sched,
                                                delay,
                                                &client_delayed_retry, th);
index 9bf2aa975a2661b2f974b4dc3da1fae813a68ee3..f88a7b5f2cf60f6364728a5f963088a5a732d8b3 100644 (file)
@@ -1343,6 +1343,9 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       /* no data ready for writing, terminate write loop */
       return;
     }
+  GNUNET_assert (have <= sock->write_buffer_size);
+  GNUNET_assert (have + sock->write_buffer_pos <= sock->write_buffer_size);
+  GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
 RETRY:
   ret = GNUNET_NETWORK_socket_send (sock->sock,
                                     &sock->write_buffer[sock->
index 4dcabface2b20d4e8ec947b2b3dad4ba009cd42c..70f9128cc8da465f52c2b692e6ae9dac7de5110f 100644 (file)
@@ -516,7 +516,8 @@ main (int argc, char *const *argv)
   ret = (GNUNET_OK ==
          GNUNET_SERVICE_run (argc,
                              argv,
-                             "resolver", &run, NULL)) ? 0 : 1;
+                             "resolver", GNUNET_SERVICE_OPTION_NONE,
+                            &run, NULL)) ? 0 : 1;
 
   while (head != NULL)
     {
index 16f65b457bfa1096f32471534582e500ba441578..dc428e592e95b8ab333d94fa6d4a61d2b821ec2f 100644 (file)
@@ -560,6 +560,13 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
           timeout = GNUNET_TIME_UNIT_ZERO;
         }
       ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout);
+      if (ret == GNUNET_SYSERR)
+        {
+          if (errno == EINTR)
+            continue;
+          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
+          break;
+        }
 #ifndef MINGW
       if (GNUNET_NETWORK_fdset_handle_isset (rs, pr))
        {
@@ -584,13 +591,6 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls)
                       _("Looks like we're busy waiting...\n"));
           sleep (1);            /* mitigate */
         }
-      if (ret == GNUNET_SYSERR)
-        {
-          if (errno == EINTR)
-            continue;
-          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
-          break;
-        }
       check_ready (&sched, rs, ws);
       run_ready (&sched);
     }
index ff9c8c192bfddf71b9e8e8acb618e517c7ef23b6..af26d278c08e34735171df1b7d70517602d48e64 100644 (file)
@@ -122,11 +122,6 @@ struct GNUNET_SERVER_Handle
    */
   size_t maxbuf;
 
-  /**
-   * Pipe used to signal shutdown of the server.
-   */
-  struct GNUNET_DISK_PipeHandle *shutpipe;
-
   /**
    * Socket used to listen for new connections.  Set to
    * "-1" by GNUNET_SERVER_destroy to initiate shutdown.
@@ -134,9 +129,9 @@ struct GNUNET_SERVER_Handle
   struct GNUNET_NETWORK_Handle *listen_socket;
 
   /**
-   * Set to GNUNET_YES if we are shutting down.
+   * Task scheduled to do the listening.
    */
-  int do_shutdown;
+  GNUNET_SCHEDULER_TaskIdentifier listen_task;
 
   /**
    * Do we ignore messages of types that we do not
@@ -261,42 +256,6 @@ struct GNUNET_SERVER_Client
 };
 
 
-/**
- * Server has been asked to shutdown, free resources.
- */
-static void
-destroy_server (struct GNUNET_SERVER_Handle *server)
-{
-  struct GNUNET_SERVER_Client *pos;
-  struct HandlerList *hpos;
-  struct NotifyList *npos;
-
-#if DEBUG_SERVER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
-#endif
-  GNUNET_assert (server->listen_socket == NULL);
-  if (GNUNET_OK != GNUNET_DISK_pipe_close (server->shutpipe))
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "pipe-close");
-  while (server->clients != NULL)
-    {
-      pos = server->clients;
-      server->clients = pos->next;
-      pos->server = NULL;
-    }
-  while (NULL != (hpos = server->handlers))
-    {
-      server->handlers = hpos->next;
-      GNUNET_free (hpos);
-    }
-  while (NULL != (npos = server->disconnect_notify_list))
-    {
-      server->disconnect_notify_list = npos->next;
-      GNUNET_free (npos);
-    }
-  GNUNET_free (server);
-}
-
-
 /**
  * Scheduler says our listen socket is ready.
  * Process it!
@@ -309,26 +268,23 @@ process_listen_socket (void *cls,
   struct GNUNET_CONNECTION_Handle *sock;
   struct GNUNET_SERVER_Client *client;
   struct GNUNET_NETWORK_FDSet *r;
-  const struct GNUNET_DISK_FileHandle *shutpipe;
 
-  if ((server->do_shutdown) ||
-      ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0))
+  server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+  r = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_set (r, server->listen_socket);
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     {
-      /* shutdown was initiated */
-      GNUNET_assert (server->listen_socket != NULL);
-      GNUNET_break (GNUNET_OK ==
-                    GNUNET_NETWORK_socket_close (server->listen_socket));
-      server->listen_socket = NULL;
-      if (server->do_shutdown)
-        destroy_server (server);
-      return;
+      server->listen_task = GNUNET_SCHEDULER_add_select (server->sched,
+                                                        GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                        GNUNET_SCHEDULER_NO_TASK,
+                                                        GNUNET_TIME_UNIT_FOREVER_REL,
+                                                        r, NULL, &process_listen_socket, 
+                                                        server);
+      GNUNET_NETWORK_fdset_destroy (r);
+      return; /* ignore shutdown, someone else will take care of it! */
     }
-  shutpipe = GNUNET_DISK_pipe_handle (server->shutpipe,
-                                      GNUNET_DISK_PIPE_END_READ);
   GNUNET_assert (GNUNET_NETWORK_fdset_isset
-                 (tc->read_ready, server->listen_socket));
-  GNUNET_assert (!GNUNET_NETWORK_fdset_handle_isset
-                 (tc->read_ready, shutpipe));
+                 (tc->read_ready, server->listen_socket));  
   sock =
     GNUNET_CONNECTION_create_from_accept (tc->sched, server->access,
                                           server->access_cls,
@@ -345,14 +301,11 @@ process_listen_socket (void *cls,
       GNUNET_SERVER_client_drop (client);
     }
   /* listen for more! */
-  r = GNUNET_NETWORK_fdset_create ();
-  GNUNET_NETWORK_fdset_set (r, server->listen_socket);
-  GNUNET_NETWORK_fdset_handle_set (r, shutpipe);
-  GNUNET_SCHEDULER_add_select (server->sched,
-                               GNUNET_SCHEDULER_PRIORITY_HIGH,
-                               GNUNET_SCHEDULER_NO_TASK,
-                               GNUNET_TIME_UNIT_FOREVER_REL,
-                               r, NULL, &process_listen_socket, server);
+  server->listen_task = GNUNET_SCHEDULER_add_select (server->sched,
+                                                    GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                    GNUNET_SCHEDULER_NO_TASK,
+                                                    GNUNET_TIME_UNIT_FOREVER_REL,
+                                                    r, NULL, &process_listen_socket, server);
   GNUNET_NETWORK_fdset_destroy (r);
 }
 
@@ -454,12 +407,6 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
         return NULL;
     }
   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
-  if (NULL == (ret->shutpipe = GNUNET_DISK_pipe (GNUNET_NO)))
-    {
-      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lsock));
-      GNUNET_free (ret);
-      return NULL;
-    }
   ret->sched = sched;
   ret->maxbuf = maxbuf;
   ret->idle_timeout = idle_timeout;
@@ -471,14 +418,11 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
     {
       r = GNUNET_NETWORK_fdset_create ();
       GNUNET_NETWORK_fdset_set (r, ret->listen_socket);
-      GNUNET_NETWORK_fdset_handle_set (r,
-                                       GNUNET_DISK_pipe_handle (ret->shutpipe,
-                                                                GNUNET_DISK_PIPE_END_READ));
-      GNUNET_SCHEDULER_add_select (sched, 
-                                   GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                   GNUNET_SCHEDULER_NO_TASK,
-                                   GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
-                                   &process_listen_socket, ret);
+      ret->listen_task = GNUNET_SCHEDULER_add_select (sched, 
+                                                     GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                     GNUNET_SCHEDULER_NO_TASK,
+                                                     GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+                                                     &process_listen_socket, ret);
       GNUNET_NETWORK_fdset_destroy (r);
     }
   return ret;
@@ -491,18 +435,40 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
 void
 GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
 {
-  static char c;
-
-  GNUNET_assert (s->do_shutdown == GNUNET_NO);
-  s->do_shutdown = GNUNET_YES;
-  if (s->listen_socket == NULL)
-    destroy_server (s);
-  else
-    GNUNET_break (1 ==
-                  GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
-                                          (s->shutpipe,
-                                           GNUNET_DISK_PIPE_END_WRITE), &c,
-                                          sizeof (c)));
+  struct GNUNET_SERVER_Client *pos;
+  struct HandlerList *hpos;
+  struct NotifyList *npos;
+
+#if DEBUG_SERVER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
+#endif
+  if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
+    {
+      GNUNET_SCHEDULER_cancel (s->sched,
+                              s->listen_task);
+      s->listen_task = GNUNET_SCHEDULER_NO_TASK;
+    }
+  GNUNET_break (GNUNET_OK ==
+               GNUNET_NETWORK_socket_close (s->listen_socket));
+  s->listen_socket = NULL;
+  while (s->clients != NULL)
+    {
+      pos = s->clients;
+      s->clients = pos->next;
+      pos->server = NULL;
+    }
+  while (NULL != (hpos = s->handlers))
+    {
+      s->handlers = hpos->next;
+      GNUNET_free (hpos);
+    }
+  while (NULL != (npos = s->disconnect_notify_list))
+    {
+      s->disconnect_notify_list = npos->next;
+      GNUNET_free (npos);
+    }
+  GNUNET_free (s);
+
 }
 
 
index 173c0f566769a9ac166b6922179c990d39130bcf..60da8788faa12dc71aca89af0a0bad33bf71106e 100644 (file)
@@ -513,6 +513,11 @@ struct GNUNET_SERVICE_Context
    */
   int allow_shutdown;
 
+  /**
+   * Our options.
+   */
+  enum GNUNET_SERVICE_Options options;
+
   /**
    * Length of addr.
    */
@@ -1108,10 +1113,15 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       sctx->ret = GNUNET_SYSERR;
       return;
     }
-  GNUNET_SCHEDULER_add_delayed (tc->sched,
-                               GNUNET_TIME_UNIT_FOREVER_REL,
-                               &shutdown_task,
-                               sctx->server);
+  if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
+    {
+      /* install a task that will kill the server
+        process if the scheduler ever gets a shutdown signal */
+      GNUNET_SCHEDULER_add_delayed (tc->sched,
+                                   GNUNET_TIME_UNIT_FOREVER_REL,
+                                   &shutdown_task,
+                                   sctx->server);
+    }
   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
   memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
   i = 0;
@@ -1277,6 +1287,7 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
  * @param argc number of command line arguments
  * @param argv command line arguments
  * @param serviceName our service name
+ * @param opt service options
  * @param task main task of the service
  * @param task_cls closure for task
  * @return GNUNET_SYSERR on error, GNUNET_OK
@@ -1286,6 +1297,7 @@ int
 GNUNET_SERVICE_run (int argc,
                     char *const *argv,
                     const char *serviceName,
+                   enum GNUNET_SERVICE_Options opt,
                     GNUNET_SERVICE_Main task,
                     void *task_cls)
 {
@@ -1311,6 +1323,7 @@ GNUNET_SERVICE_run (int argc,
   loglev = GNUNET_strdup ("WARNING");
   cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_DAEMON_CONFIG_FILE);
   memset (&sctx, 0, sizeof (sctx));
+  sctx.options = opt;
   sctx.ready_confirm_fd = -1;
   sctx.ret = GNUNET_OK;
   sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
index 9e6a29ea487fb4183cc29d83024e1a08f7b05c46..7a23855c5ee96686bdbdc4c551969956d7189672 100644 (file)
@@ -45,6 +45,7 @@ iterator_callback (void *cls, void *element, GNUNET_CONTAINER_HeapCost cost)
   return GNUNET_OK;
 }
 
+
 int
 main (int argc, char **argv)
 {
@@ -68,23 +69,23 @@ main (int argc, char **argv)
   neighbor6.cost = 30;
 
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor1, neighbor1.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor2, neighbor2.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor3, neighbor3.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor4, neighbor4.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor5, neighbor5.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_insert (myHeap, &neighbor6, neighbor6.cost);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_remove_node (myHeap, &neighbor5);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_remove_root (myHeap);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_update_cost (myHeap, &neighbor6, 200);
-  GNUNET_CONTAINER_heap_iterate (myHeap, iterator_callback, NULL);
+  GNUNET_CONTAINER_heap_iterate (myHeap, &iterator_callback, NULL);
   GNUNET_CONTAINER_heap_destroy (myHeap);
 
   return 0;
index 30fc34b08462defaa65b4face36d9c02cb0dd5f5..7b35647ea8c7aa0e8f3ea5a983866c2b5abcf489 100644 (file)
@@ -120,8 +120,11 @@ disconnect_notify (void *cls, const struct GNUNET_MessageHeader *msg)
   GNUNET_assert (ok == 7);
   ok = 0;
   GNUNET_CLIENT_disconnect (client);
-  GNUNET_SCHEDULER_shutdown (sched);
+  client = NULL;
+  GNUNET_SERVER_destroy (server);
+  server = NULL;
   GNUNET_CONFIGURATION_destroy (cfg);
+  cfg = NULL;
 }
 
 
index 860ed3837ad2ad25f7c11be3ad51f0a6aed96677..52b0addfaa484a8ef895124481fd2063edb592c0 100644 (file)
@@ -103,6 +103,16 @@ recv_cb (void *cls,
 }
 
 
+static void
+clean_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  GNUNET_SERVER_destroy (server);
+  server = NULL;
+  GNUNET_CONFIGURATION_destroy (cfg);
+  cfg = NULL;
+}
+
+
 /**
  * Functions with this signature are called whenever a client
  * is disconnected on the network level.
@@ -115,8 +125,9 @@ notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
 {
   GNUNET_assert (ok == 5);
   ok = 0;
-  GNUNET_SCHEDULER_shutdown (sched);
-  GNUNET_CONFIGURATION_destroy (cfg);
+  GNUNET_SCHEDULER_add_delayed (sched,
+                               GNUNET_TIME_UNIT_ZERO,
+                               &clean_up, NULL); 
 }
 
 
index fa35da6e9cd4a27eecb760cb6869f6cb421e837d..ab7011526251d749b2ecbb766328c393a2376ffd 100644 (file)
@@ -152,6 +152,7 @@ check ()
                  GNUNET_SERVICE_run (5,
                                      argv,
                                      "test_service",
+                                    GNUNET_SERVICE_OPTION_NONE,
                                      &runner, &ok));
   GNUNET_assert (0 == ok);
   return ok;
@@ -213,6 +214,7 @@ check6 ()
                  GNUNET_SERVICE_run (5,
                                      argv,
                                      "test_service6",
+                                    GNUNET_SERVICE_OPTION_NONE,
                                      &runner6, &ok));
   GNUNET_assert (0 == ok);
   return ok;
@@ -245,6 +247,7 @@ check6d ()
                  GNUNET_SERVICE_run (6,
                                      argv,
                                      "test_service6",
+                                    GNUNET_SERVICE_OPTION_NONE,
                                      &runner6, &ok));
   GNUNET_break (0 == ok);
   return ok;