fix
[oweals/gnunet.git] / src / fs / gnunet-service-fs_drq.c
index dc9560be67ea33d539756aaa111687de9eae90e5..b549c6707ab5979988bd9eb5758eeb45ad7b9aea 100644 (file)
@@ -26,6 +26,7 @@
 #include "platform.h"
 #include "gnunet-service-fs_drq.h"
 
+#define DEBUG_DRQ GNUNET_NO
 
 /**
  * Signature of a function that is called whenever a datastore
@@ -82,7 +83,7 @@ struct DatastoreRequestQueue
   /**
    * Datastore entry type we are doing the 'get' for.
    */
-  uint32_t type;
+  enum GNUNET_BLOCK_Type type;
 
   /**
    * Is this request at the head of the queue irrespective of its
@@ -112,10 +113,6 @@ static struct DatastoreRequestQueue *drq_head;
  */
 static struct DatastoreRequestQueue *drq_tail;
 
-/**
- * Our connection to the datastore.
- */
-static struct GNUNET_DATASTORE_Handle *dsh;
 
 /**
  * Pointer to the currently actively running request,
@@ -153,7 +150,7 @@ get_iterator (void *cls,
              const GNUNET_HashCode * key,
              uint32_t size,
              const void *data,
-             uint32_t type,
+             enum GNUNET_BLOCK_Type type,
              uint32_t priority,
              uint32_t anonymity,
              struct GNUNET_TIME_Absolute
@@ -165,17 +162,32 @@ get_iterator (void *cls,
   if (gc->iter == NULL) 
     {
       /* stop the iteration */
+#if DEBUG_DRQ
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Iteration terminated\n");
+#endif
       if (key != NULL)
        GNUNET_DATASTORE_get_next (dsh, GNUNET_NO);
     }
   else
     {
+#if DEBUG_DRQ
+      if (key != NULL)
+       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                   "Iteration produced %u-byte result for `%s'\n",
+                   size,
+                   GNUNET_h2s (key));
+#endif
       gc->iter (gc->iter_cls,
                key, size, data, type,
                priority, anonymity, expiration, uid);
     }
   if (key == NULL)
     {
+#if DEBUG_DRQ
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Iteration completed\n");
+#endif
       GNUNET_assert (gc == drq_running);
       GNUNET_free (gc);
       drq_running = NULL;
@@ -197,10 +209,19 @@ run_next_request (void *cls,
   struct DatastoreRequestQueue *gc = cls;
 
   gc->task = GNUNET_SCHEDULER_NO_TASK;
-  GNUNET_DATASTORE_get (dsh, &gc->key, gc->type, 
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Running datastore request for `%s' of type %u\n",
+             GNUNET_h2s (&gc->key),
+             gc->type);
+#endif
+  GNUNET_DATASTORE_get (dsh, 
+                       &gc->key,
+                       gc->type, 
+                       42 /* FIXME */, 64 /* FIXME */,
+                       GNUNET_TIME_absolute_get_remaining(gc->timeout),
                        &get_iterator,
-                       gc,
-                       GNUNET_TIME_absolute_get_remaining(gc->timeout));
+                       gc);
 }
 
 
@@ -239,6 +260,10 @@ timeout_ds_request (void *cls,
 {
   struct DatastoreRequestQueue *e = cls;
 
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Datastore request timed out in queue before transmission\n");
+#endif
   e->task = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e);
   if (e->iter != NULL)
@@ -261,10 +286,11 @@ shutdown_task (void *cls,
 {
   struct DatastoreRequestQueue *drq;
 
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "DRQ shutdown initiated\n");
+#endif
   GNUNET_assert (NULL != dsh);
-  GNUNET_DATASTORE_disconnect (dsh,
-                              GNUNET_NO);
-  dsh = NULL;
   while (NULL != (drq = drq_head))
     {
       drq_head = drq->next;
@@ -276,6 +302,22 @@ shutdown_task (void *cls,
       GNUNET_free (drq);
     }
   drq_tail = NULL;
+  if (drq_running != NULL)
+    {
+      if (drq_running->task != GNUNET_SCHEDULER_NO_TASK)
+       {
+         GNUNET_SCHEDULER_cancel (sched,
+                                  drq_running->task);
+       }
+      if (drq_running->iter != NULL)
+       {
+         drq_running->iter (drq_running->iter_cls,
+                            NULL, 0, NULL, 0, 0, 0, 
+                            GNUNET_TIME_UNIT_ZERO_ABS, 0);
+       }
+      GNUNET_free (drq_running);
+      drq_running = NULL;
+    }
 }
 
 
@@ -297,7 +339,7 @@ shutdown_task (void *cls,
  */
 struct DatastoreRequestQueue *
 GNUNET_FS_drq_get (const GNUNET_HashCode * key,
-                  uint32_t type,
+                  enum GNUNET_BLOCK_Type type,
                   GNUNET_DATASTORE_Iterator iter, 
                   void *iter_cls,
                   struct GNUNET_TIME_Relative timeout,
@@ -306,6 +348,12 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key,
   struct DatastoreRequestQueue *e;
   struct DatastoreRequestQueue *bef;
 
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "DRQ receives request for `%s' of type %u\n",
+             GNUNET_h2s (key),
+             type);
+#endif
   e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue));
   e->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   e->forced_head = immediate;
@@ -348,6 +396,10 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key,
 void
 GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq)
 {
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "DRQ receives request cancellation request\n");
+#endif
   if (drq == drq_running)
     {
       /* 'DATASTORE_get' has already been started (and this call might
@@ -376,10 +428,40 @@ GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq)
 void
 GNUNET_FS_drq_get_next (int more)
 {
+#if DEBUG_DRQ
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "DRQ receives request for next result (more is %d)\n",
+             more);
+#endif
   GNUNET_DATASTORE_get_next (dsh, more);
 }
 
 
+/**
+ * Closure for 'drq_remove_cont'.
+ */
+struct RemoveContext
+{
+  struct GNUNET_DATASTORE_Handle *rmdsh; 
+  GNUNET_DATASTORE_ContinuationWithStatus cont;
+  void *cont_cls;
+};
+
+
+static void 
+drq_remove_cont (void *cls,
+                int success,
+                const char *msg)
+{
+  struct RemoveContext *rc = cls;
+
+  rc->cont (rc->cont_cls,
+           success,
+           msg);
+  GNUNET_free (rc);
+}
+
+
 /**
  * Explicitly remove some content from the database.
  * The "cont"inuation will be called with status
@@ -401,13 +483,26 @@ GNUNET_FS_drq_remove (const GNUNET_HashCode *key,
                      void *cont_cls,
                      struct GNUNET_TIME_Relative timeout)
 {
-  if (dsh == NULL)
+  struct GNUNET_DATASTORE_Handle *rmdsh; 
+  struct RemoveContext *rc;
+
+  if (rmdsh == NULL)
     {
       GNUNET_break (0);
+      cont (cont_cls,
+           GNUNET_SYSERR,
+           _("Failed to connect to datastore"));
       return;
     }
-  GNUNET_DATASTORE_remove (dsh, key, size, data,
-                          cont, cont_cls, timeout);
+  rc = GNUNET_malloc (sizeof (struct RemoveContext));
+  rc->cont = cont;
+  rc->cont_cls = cont_cls;
+  rc->rmdsh = rmdsh;
+  GNUNET_DATASTORE_remove (rmdsh, key, size, data,
+                          -3, 128,
+                          timeout,
+                          &drq_remove_cont, 
+                          rc);
 }