Merge branch 'master' of gnunet.org:gnunet
[oweals/gnunet.git] / src / fs / fs_publish_ublock.c
index 79136607396e05e8ec036842a838761f9bb46bf6..e21443ccbf994eb4d79899be0f0e7b5fb4f3df63 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
@@ -108,16 +108,22 @@ struct GNUNET_FS_PublishUblockContext
    * Handle for active datastore operation.
    */
   struct GNUNET_DATASTORE_QueueEntry *qre;
+
+  /**
+   * Task to run continuation asynchronously.
+   */
+  struct GNUNET_SCHEDULER_Task * task;
+
 };
 
 
 /**
- * Continuation of "GNUNET_FS_publish_ublock_".
+ * Continuation of #GNUNET_FS_publish_ublock_().
  *
  * @param cls closure of type "struct GNUNET_FS_PublishUblockContext*"
- * @param success GNUNET_SYSERR on failure (including timeout/queue drop)
- *                GNUNET_NO if content was already there
- *                GNUNET_YES (or other positive value) on success
+ * @param success #GNUNET_SYSERR on failure (including timeout/queue drop)
+ *                #GNUNET_NO if content was already there
+ *                #GNUNET_YES (or other positive value) on success
  * @param min_expiration minimum expiration time required for 0-priority content to be stored
  *                by the datacache at this time, zero for unknown, forever if we have no
  *                space for 0-priority content
@@ -137,6 +143,22 @@ ublock_put_cont (void *cls,
 }
 
 
+/**
+ * Run the continuation.
+ *
+ * @param cls the `struct GNUNET_FS_PublishUblockContext *`
+ */
+static void
+run_cont (void *cls)
+{
+  struct GNUNET_FS_PublishUblockContext *uc = cls;
+
+  uc->task = NULL;
+  uc->cont (uc->cont_cls, NULL);
+  GNUNET_free (uc);
+}
+
+
 /**
  * Publish a UBlock.
  *
@@ -150,8 +172,8 @@ ublock_put_cont (void *cls,
  * @param bo per-block options
  * @param options publication options
  * @param cont continuation
- * @param cont_cls closure for cont
- * @return NULL on error ('cont' will still be called)
+ * @param cont_cls closure for @a cont
+ * @return NULL on error (@a cont will still be called)
  */
 struct GNUNET_FS_PublishUblockContext *
 GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
@@ -202,9 +224,9 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
   ub_plain = GNUNET_malloc (size);
   kbe = (char *) &ub_plain[1];
   if (NULL != ulabel)
-    memcpy (kbe, ulabel, ulen);
+    GNUNET_memcpy (kbe, ulabel, ulen);
   kbe += ulen;
-  memcpy (kbe, uris, slen);
+  GNUNET_memcpy (kbe, uris, slen);
   kbe += slen;
   GNUNET_free (uris);
   sptr = kbe;
@@ -236,6 +258,7 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
                             ulen + slen + mdsize,
                             &skey, &iv,
                              &ub_enc[1]);
+  GNUNET_free (ub_plain);
   ub_enc->purpose.size = htonl (ulen + slen + mdsize +
                                sizeof (struct UBlock)
                                - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
@@ -257,14 +280,27 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
   uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext);
   uc->cont = cont;
   uc->cont_cls = cont_cls;
-  uc->qre =
-    GNUNET_DATASTORE_put (dsh, 0, &query,
-                         ulen + slen + mdsize + sizeof (struct UBlock),
-                         ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK,
-                         bo->content_priority, bo->anonymity_level,
-                         bo->replication_level, bo->expiration_time,
-                         -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
-                         &ublock_put_cont, uc);
+  if (NULL != dsh)
+  {
+    uc->qre =
+      GNUNET_DATASTORE_put (dsh,
+                            0,
+                            &query,
+                            ulen + slen + mdsize + sizeof (struct UBlock),
+                            ub_enc,
+                            GNUNET_BLOCK_TYPE_FS_UBLOCK,
+                            bo->content_priority,
+                            bo->anonymity_level,
+                            bo->replication_level,
+                            bo->expiration_time,
+                            -2, 1,
+                            &ublock_put_cont, uc);
+  }
+  else
+  {
+    uc->task = GNUNET_SCHEDULER_add_now (&run_cont,
+                                         uc);
+  }
   return uc;
 }
 
@@ -277,6 +313,11 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
 void
 GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc)
 {
-  GNUNET_DATASTORE_cancel (uc->qre);
+  if (NULL != uc->qre)
+    GNUNET_DATASTORE_cancel (uc->qre);
+  if (NULL != uc->task)
+    GNUNET_SCHEDULER_cancel (uc->task);
   GNUNET_free (uc);
 }
+
+/* end of fs_publish_ublock.c */