finish publish shutdown code
authorChristian Grothoff <christian@grothoff.org>
Sat, 29 Aug 2009 21:17:42 +0000 (21:17 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sat, 29 Aug 2009 21:17:42 +0000 (21:17 +0000)
src/fs/fs.h
src/fs/fs_publish.c

index 3f1ffad306579e283f0d6df94ab8ae06fe57b7dc..66190a42d8107178224ded24a9dc718a9c9615f4 100644 (file)
@@ -429,6 +429,21 @@ struct GNUNET_FS_PublishContext
    */
   GNUNET_SCHEDULER_TaskIdentifier upload_task;
 
+  /**
+   * Typically GNUNET_NO.  Set to GNUNET_YES if
+   * "upload_task" is GNUNET_SCHEDULER_NO_TASK
+   * and we're waiting for a response from the
+   * datastore service (in which case this
+   * struct must not be freed until we have that
+   * response).  If someone tries to stop the
+   * download for good during this period, 
+   * "in_network_wait" is set to GNUNET_SYSERR
+   * which will cause the struct to be destroyed
+   * right after we have the reply (or timeout)
+   * from the datastore service.
+   */
+  int in_network_wait;
+
   /**
    * Current position in the file-tree for the
    * upload.
index 0cdc3811b054904fcf10395bcc7b5e147efc765a..6a8bfc97a8db92d166abbb13216cee3f4e31a692 100644 (file)
@@ -106,6 +106,24 @@ make_publish_status (struct GNUNET_FS_ProgressInfo *pi,
 }
 
 
+/**
+ * Cleanup the publish context, we're done
+ * with it.
+ *
+ * @param pc struct to clean up after
+ */
+static void
+publish_cleanup (struct GNUNET_FS_PublishContext *sc)
+{
+  GNUNET_FS_file_information_destroy (sc->fi, NULL, NULL);
+  GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO);
+  GNUNET_free_non_null (sc->nid);  
+  GNUNET_free_non_null (sc->nuid);
+  GNUNET_DATASTORE_disconnect (sc->dsh, GNUNET_NO);
+  GNUNET_free (sc);
+}
+
+
 /**
  * Function called by the datastore API with
  * the result from the PUT request.
@@ -122,6 +140,15 @@ ds_put_cont (void *cls,
   struct PutContCtx *pcc = cls;
   struct GNUNET_FS_ProgressInfo pi;
 
+  if (GNUNET_SYSERR == pcc->sc->in_network_wait)
+    {
+      /* we were aborted in the meantime,
+        finish shutdown! */
+      publish_cleanup (pcc->sc);
+      return;
+    }
+  GNUNET_assert (GNUNET_YES == pcc->sc->in_network_wait);
+  pcc->sc->in_network_wait = GNUNET_NO;
   if (GNUNET_OK != success)
     {
       GNUNET_asprintf (&pcc->p->emsg, 
@@ -178,10 +205,8 @@ publish_block (struct GNUNET_FS_PublishContext *sc,
   dpc_cls->cont = cont;
   dpc_cls->sc = sc;
   dpc_cls->p = p;
-  // FIXME: need to do something to "sc" to mark
-  // that "sc" can not be freed right now due to this
-  // pending, scheduled operation for which we don't have
-  // a task ID!  
+  GNUNET_assert (GNUNET_NO == sc->in_network_wait);
+  sc->in_network_wait = GNUNET_YES;
   GNUNET_DATASTORE_put (sc->dsh,
                        sc->rid,
                        query,
@@ -798,12 +823,13 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *sc)
   GNUNET_FS_file_information_inspect (sc->fi,
                                      &fip_signal_stop,
                                      sc);
-  GNUNET_FS_file_information_destroy (sc->fi, NULL, NULL);
-  GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO);
-  GNUNET_free_non_null (sc->nid);  
-  GNUNET_free_non_null (sc->nuid);
-  GNUNET_DATASTORE_disconnect (sc->dsh, GNUNET_NO);
-  GNUNET_free (sc);
+  if (GNUNET_YES == sc->in_network_wait)
+    {
+      sc->in_network_wait = GNUNET_SYSERR;
+      return;
+    }
+  publish_cleanup (sc);
 }
 
+
 /* end of fs_publish.c */