*/
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.
}
+/**
+ * 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.
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,
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,
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 */