[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r925 - in GNUnet: . contrib src/applications/fs/ecrs src/ap
From: |
grothoff |
Subject: |
[GNUnet-SVN] r925 - in GNUnet: . contrib src/applications/fs/ecrs src/applications/fs/fsui src/applications/fs/tools src/include |
Date: |
Tue, 14 Jun 2005 09:58:27 -0700 (PDT) |
Author: grothoff
Date: 2005-06-14 09:58:05 -0700 (Tue, 14 Jun 2005)
New Revision: 925
Modified:
GNUnet/contrib/gnunet.root
GNUnet/src/applications/fs/ecrs/upload.c
GNUnet/src/applications/fs/fsui/download.c
GNUnet/src/applications/fs/fsui/fsui.c
GNUnet/src/applications/fs/fsui/fsui.h
GNUnet/src/applications/fs/fsui/search.c
GNUnet/src/applications/fs/fsui/unindex.c
GNUnet/src/applications/fs/fsui/upload.c
GNUnet/src/applications/fs/tools/gnunet-download.c
GNUnet/src/applications/fs/tools/gnunet-insert.c
GNUnet/src/applications/fs/tools/gnunet-search.c
GNUnet/src/applications/fs/tools/gnunet-unindex.c
GNUnet/src/include/gnunet_fsui_lib.h
GNUnet/todo
Log:
partial bugfixes
Modified: GNUnet/contrib/gnunet.root
===================================================================
--- GNUnet/contrib/gnunet.root 2005-06-13 20:56:27 UTC (rev 924)
+++ GNUnet/contrib/gnunet.root 2005-06-14 16:58:05 UTC (rev 925)
@@ -562,6 +562,14 @@
# Default is $GNUNETD_HOME/data/shared/
INDEX-DIRECTORY = $GNUNETD_HOME/data/shared/
+# How many (parallel) threads should a given gnunet-download (or
+# gnunet-gtk) process run? (this limits the amount of parallelism
+# used in the FSUI library). Smaller values reduce memory and CPU
+# requirements. Very large values will not be useful since even if
+# that much parallelism is theoretically possible, the local node may
+# not be able to route that many parallel requests anyway.
+# Default: 32
+POOL = 32
#######################################
# MySQL specific options.
Modified: GNUnet/src/applications/fs/ecrs/upload.c
===================================================================
--- GNUnet/src/applications/fs/ecrs/upload.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/ecrs/upload.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -204,11 +204,12 @@
switch(FS_initIndex(sock, &fileId, filename)) {
case SYSERR:
- LOG(LOG_ERROR, "'%s' failed.\n", _("Initialization"));
+ LOG(LOG_ERROR, _("Initialization for indexing file '%s'
failed.\n"), filename);
return SYSERR;
case NO:
- LOG(LOG_ERROR, "Indexing %s failed. Check file
permissions and consult "
- "your GNUnet server's logs.\n", filename);
+ LOG(LOG_ERROR,
+ _("Indexing file '%s' failed. Check file
permissions and consult "
+ "your GNUnet server's logs.\n"), filename);
return SYSERR;
}
Modified: GNUnet/src/applications/fs/fsui/download.c
===================================================================
--- GNUnet/src/applications/fs/fsui/download.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/download.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -23,13 +23,6 @@
* @brief download functions
* @author Krista Bennett
* @author Christian Grothoff
- *
- * BIG FIXME: the download code still has some very serious issues in
- * particular with recursive downloads (and the tree model of them).
- * This may result in segfaults on exit and other bad side-effects.
- *
- * Also, it spawns far, far too many concurrent threads (lots to be
- * fixed, probably including a re-design to clean things up).
*/
#include "platform.h"
@@ -37,6 +30,7 @@
#include "gnunet_fsui_lib.h"
#include "fsui.h"
+
/**
* Start to download a file.
*
@@ -63,12 +57,12 @@
if (ECRS_equalsUri(parent->completedDownloads[i],
fi->uri))
return OK; /* already complete! */
- pos = parent->subDownloads;
+ pos = parent->child;
while (pos != NULL) {
if (ECRS_equalsUri(pos->uri,
fi->uri))
return OK; /* already downloading */
- pos = pos->subDownloadsNext;
+ pos = pos->next;
}
filename = ECRS_getFromMetaData(fi->meta,
EXTRACTOR_FILENAME);
@@ -113,11 +107,12 @@
FSUI_DownloadList * root;
root = dl;
- while (root->parent != NULL)
+ while ( (root->parent != NULL) &&
+ (root->parent != &dl->ctx->activeDownloads) )
root = root->parent;
dl->completed = completedBytes;
- event.type = download_progress;
+ event.type = FSUI_download_progress;
event.data.DownloadProgress.total = totalBytes;
event.data.DownloadProgress.completed = completedBytes;
event.data.DownloadProgress.last_offset = lastBlockOffset;
@@ -130,6 +125,7 @@
event.data.DownloadProgress.is_recursive = dl->is_recursive;
event.data.DownloadProgress.main_filename = root->filename;
event.data.DownloadProgress.main_uri = root->uri;
+ event.data.DownloadProgress.pos = dl;
dl->ctx->ecb(dl->ctx->ecbClosure,
&event);
if ( (lastBlockOffset == 0) &&
@@ -175,19 +171,15 @@
void * downloadThread(FSUI_DownloadList * dl) {
int ret;
FSUI_Event event;
- unsigned long long totalBytes;
- FSUI_DownloadList * prev;
- FSUI_DownloadList * pos;
struct ECRS_MetaData * md;
FSUI_DownloadList * root;
+ unsigned long long totalBytes;
- totalBytes = ECRS_fileSize(dl->uri);
+ GNUNET_ASSERT(dl->ctx != NULL);
root = dl;
- while (root->parent != NULL) {
+ while ( (root->parent != NULL) &&
+ (root->parent != &dl->ctx->activeDownloads) ) {
root = root->parent;
- if (root != NULL) {
- root->total += totalBytes;
- }
}
GNUNET_ASSERT(dl->filename != NULL);
@@ -198,24 +190,11 @@
dl,
(ECRS_TestTerminate) &testTerminate,
dl);
- if (ret != OK) {
- event.type = download_error;
- event.data.message = _("Download aborted.");
- } else {
- event.type = download_complete;
- event.data.DownloadProgress.total = root->total;
- event.data.DownloadProgress.completed = root->completed;
- event.data.DownloadProgress.last_offset = 0;
- event.data.DownloadProgress.eta = cronTime(NULL);
- event.data.DownloadProgress.last_block = NULL;
- event.data.DownloadProgress.last_size = 0;
- event.data.DownloadProgress.filename = dl->filename;
- event.data.DownloadProgress.uri = dl->uri;
- event.data.DownloadProgress.start_time = dl->startTime;
- event.data.DownloadProgress.is_recursive = dl->is_recursive;
- event.data.DownloadProgress.main_filename = root->filename;
- event.data.DownloadProgress.main_uri = root->uri;
- }
+ /* MAYBE FIXME: ___ ret == OK possible without download complete or at
+ least without downloadProgressCallback called with complete?? __
+ (possibly only with resumed download???) */
+ if (ret == OK)
+ dl->finished = YES;
if ( (ret == OK) &&
(dl->is_recursive) &&
(dl->is_directory) ) {
@@ -224,16 +203,18 @@
#ifdef O_LARGEFILE
fd = fileopen(dl->filename,
- O_LARGEFILE | O_RDONLY);
+ O_LARGEFILE | O_RDONLY);
#else
fd = fileopen(dl->filename,
- O_RDONLY);
+ O_RDONLY);
#endif
if (fd == -1) {
LOG_FILE_STRERROR(LOG_ERROR,
"OPEN",
dl->filename);
} else {
+ totalBytes = ECRS_fileSize(dl->uri);
+
dirBlock = MMAP(NULL,
totalBytes,
PROT_READ,
@@ -253,42 +234,43 @@
MUNMAP(dirBlock, totalBytes);
closefile(fd);
}
-
- /* wait for recursive downloads (if any) */
- while ( (dl->subDownloads != NULL) &&
- (dl->signalTerminate != YES) )
- gnunet_util_sleep(100);
}
- dl->ctx->ecb(dl->ctx->ecbClosure,
- &event);
- if (dl->parent != NULL) {
- /* notify parent that we're done */
- MUTEX_LOCK(&dl->ctx->lock);
- GROW(dl->parent->completedDownloads,
- dl->parent->completedDownloadsCount,
- dl->parent->completedDownloadsCount+1);
- dl->parent->completedDownloads[dl->parent->completedDownloadsCount-1]
- = ECRS_dupUri(dl->uri);
- prev = NULL;
- pos = dl->parent->subDownloads;
- while ( (pos != NULL) &&
- (pos != dl) ) {
- prev = pos;
- pos = pos->subDownloadsNext;
- }
- if (pos == NULL) {
- BREAK();
+ if (ret != OK) {
+ if (dl->signalTerminate == YES) {
+ event.type = FSUI_download_aborted;
+ event.data.DownloadError.message = _("Download aborted.");
} else {
- if (prev != NULL)
- prev->subDownloadsNext
- = pos->subDownloadsNext;
- else
- dl->parent->subDownloads
- = pos->subDownloadsNext;
+ event.type = FSUI_download_error;
+ event.data.DownloadError.message = _("ECRS download failed (see logs).");
}
- MUTEX_UNLOCK(&dl->ctx->lock);
+ event.data.DownloadError.pos = dl;
+ dl->ctx->ecb(dl->ctx->ecbClosure,
+ &event);
+ dl->signalTerminate = YES;
+ } else {
+ dl->signalTerminate = YES;
+ while ( (dl != NULL) &&
+ (dl->ctx != NULL) &&
+ (dl != &dl->ctx->activeDownloads) ) {
+ event.type = FSUI_download_complete;
+ event.data.DownloadProgress.total = root->total;
+ event.data.DownloadProgress.completed = root->completed;
+ event.data.DownloadProgress.last_offset = 0;
+ event.data.DownloadProgress.eta = cronTime(NULL);
+ event.data.DownloadProgress.last_block = NULL;
+ event.data.DownloadProgress.last_size = 0;
+ event.data.DownloadProgress.filename = dl->filename;
+ event.data.DownloadProgress.uri = dl->uri;
+ event.data.DownloadProgress.start_time = dl->startTime;
+ event.data.DownloadProgress.is_recursive = dl->is_recursive;
+ event.data.DownloadProgress.main_filename = root->filename;
+ event.data.DownloadProgress.main_uri = root->uri;
+ event.data.DownloadProgress.pos = dl;
+ dl->ctx->ecb(dl->ctx->ecbClosure,
+ &event);
+ dl = dl->parent;
+ }
}
- dl->signalTerminate = YES;
return NULL;
}
@@ -306,7 +288,10 @@
int is_recursive,
FSUI_DownloadList * parent) {
FSUI_DownloadList * dl;
+ FSUI_DownloadList * root;
+ unsigned long long totalBytes;
+ GNUNET_ASSERT(ctx != NULL);
if (! (ECRS_isFileUri(uri) ||
ECRS_isLocationUri(uri)) ) {
BREAK(); /* wrong type of URI! */
@@ -316,8 +301,8 @@
dl = MALLOC(sizeof(FSUI_DownloadList));
memset(dl, 0, sizeof(FSUI_DownloadList));
cronTime(&dl->startTime);
- dl->signalTerminate = NO;
- dl->threadStarted = NO;
+ dl->signalTerminate = SYSERR;
+ dl->finished = NO;
dl->is_recursive = is_recursive;
dl->parent = parent;
dl->is_directory = SYSERR; /* don't know */
@@ -326,27 +311,16 @@
dl->filename = STRDUP(filename);
dl->uri = ECRS_dupUri(uri);
dl->total = ECRS_fileSize(uri);
- MUTEX_LOCK(&ctx->lock);
- if (0 != PTHREAD_CREATE(&dl->handle,
- (PThreadMain) &downloadThread,
- dl,
- 128 * 1024)) {
- FREE(dl->filename);
- ECRS_freeUri(dl->uri);
- FREE(dl);
- MUTEX_UNLOCK(&ctx->lock);
- return SYSERR;
+ dl->next = parent->child;
+ parent->child = dl;
+
+ totalBytes = ECRS_fileSize(uri);
+ root = dl;
+ while ( (root->parent != NULL) &&
+ (root->parent != &dl->ctx->activeDownloads) ) {
+ root = root->parent;
+ root->total += totalBytes;
}
- dl->threadStarted = YES;
- if (parent != NULL) {
- /* add to pending downloads of parent! */
- dl->subDownloadsNext = parent->subDownloads;
- parent->subDownloads = dl;
- }
- dl->next = ctx->activeDownloads;
- ctx->activeDownloads = dl;
- MUTEX_UNLOCK(&ctx->lock);
- cleanupFSUIThreadList(ctx);
return OK;
}
@@ -361,16 +335,127 @@
unsigned int anonymityLevel,
const struct ECRS_URI * uri,
const char * filename) {
+ int ret;
+
GNUNET_ASSERT(filename != NULL);
- return startDownload(ctx,
- anonymityLevel,
- uri,
- filename,
- NO,
- NULL);
+ GNUNET_ASSERT(ctx != NULL);
+ MUTEX_LOCK(&ctx->lock);
+ ret = startDownload(ctx,
+ anonymityLevel,
+ uri,
+ filename,
+ NO,
+ &ctx->activeDownloads);
+ MUTEX_UNLOCK(&ctx->lock);
+ return ret;
}
/**
+ * Starts or stops download threads in accordance with thread pool
+ * size and active downloads. Call only while holding FSUI lock (or
+ * during start/stop).
+ *
+ * @return YES if change done that may require re-trying
+ */
+int updateDownloadThread(FSUI_DownloadList * list) {
+ FSUI_DownloadList * dpos;
+ void * unused;
+ int ret;
+
+ if (list == NULL)
+ return NO;
+
+ ret = NO;
+ /* should this one be started? */
+ if ( (list->ctx->threadPoolSize
+ > list->ctx->activeDownloadThreads) &&
+ (list->signalTerminate == SYSERR) &&
+ (list->total > list->completed) &&
+ (list->finished == NO) ) {
+ list->signalTerminate = NO;
+ if (0 == PTHREAD_CREATE(&list->handle,
+ (PThreadMain)&downloadThread,
+ list,
+ 32 * 1024)) {
+ list->ctx->activeDownloadThreads++;
+ } else {
+ LOG_STRERROR(LOG_WARNING, "pthread_create");
+ }
+ }
+
+ /* should this one be stopped? */
+ if ( (list->ctx->threadPoolSize
+ < list->ctx->activeDownloadThreads) &&
+ (list->signalTerminate == NO) ) {
+ list->signalTerminate = YES;
+ PTHREAD_JOIN(&list->handle,
+ &unused);
+ list->ctx->activeDownloadThreads--;
+ list->signalTerminate = SYSERR;
+ ret = YES;
+ }
+
+ /* has this one "died naturally"? */
+ if (list->signalTerminate == YES) {
+ PTHREAD_JOIN(&list->handle,
+ &unused);
+ list->ctx->activeDownloadThreads--;
+ list->signalTerminate = SYSERR;
+ ret = YES;
+ }
+
+ dpos = list->child;
+ while (dpos != NULL) {
+ if (YES == updateDownloadThread(dpos))
+ ret = YES;
+ dpos = dpos->next;
+ }
+ return ret;
+}
+
+
+/**
+ * Free the subtree (assumes all threads have already been stopped and
+ * that the FSUI lock is either held or that we are in FSUI stop!).
+ */
+void freeDownloadList(FSUI_DownloadList * list) {
+ FSUI_DownloadList * dpos;
+ int i;
+
+ GNUNET_ASSERT(list->signalTerminate != NO);
+
+ /* first, find our predecessor and
+ unlink us from the tree! */
+ dpos = list->parent;
+ if (dpos != NULL) {
+ if (dpos->child == list)
+ dpos->child = list->next;
+ else {
+ dpos = dpos->child;
+ while ( (dpos != NULL) &&
+ (dpos != list) )
+ dpos = dpos->next;
+ GNUNET_ASSERT(dpos != NULL);
+ dpos->next = list->next;
+ }
+ }
+
+ /* then, free all of our children */
+ while (list->child != NULL)
+ freeDownloadList(list->child);
+
+ /* finally, free this node and its data */
+ ECRS_freeUri(list->uri);
+ FREE(list->filename);
+ for (i=list->completedDownloadsCount-1;i>=0;i--)
+ ECRS_freeUri(list->completedDownloads[i]);
+ GROW(list->completedDownloads,
+ list->completedDownloadsCount,
+ 0);
+ FREE(list);
+}
+
+/**
* Abort a download.
*
* @return SYSERR if no such download is pending
@@ -379,18 +464,22 @@
const struct ECRS_URI * uri,
const char * filename) {
FSUI_DownloadList * dl;
+ unsigned int backup;
/* FIXME: check that filename matches
aborted download! */
GNUNET_ASSERT(filename != NULL);
MUTEX_LOCK(&ctx->lock);
- dl = ctx->activeDownloads;
+ dl = ctx->activeDownloads.child;
while (dl != NULL) {
if (ECRS_equalsUri(uri,
dl->uri)) {
- dl->signalTerminate = YES;
+ backup = ctx->threadPoolSize;
+ ctx->threadPoolSize = 0;
+ updateDownloadThread(dl);
+ freeDownloadList(dl);
+ ctx->threadPoolSize = backup;
MUTEX_UNLOCK(&ctx->lock);
- cleanupFSUIThreadList(ctx);
return OK;
}
dl = dl->next;
@@ -406,17 +495,21 @@
* events.
*/
int FSUI_listDownloads(struct FSUI_Context * ctx,
+ const FSUI_DownloadList * root,
FSUI_DownloadIterator iter,
void * closure) {
FSUI_DownloadList * dl;
int ret;
ret = 0;
- cleanupFSUIThreadList(ctx);
MUTEX_LOCK(&ctx->lock);
- dl = ctx->activeDownloads;
+ if (root == NULL)
+ dl = ctx->activeDownloads.child;
+ else
+ dl = root->child;
while (dl != NULL) {
if (OK != iter(closure,
+ dl,
dl->filename,
dl->uri,
dl->total,
@@ -434,6 +527,19 @@
}
/**
+ * Get parent of active download.
+ * @return NULL if there is no parent
+ */
+const FSUI_DownloadList *
+FSUI_getDownloadParent(const FSUI_DownloadList * child) {
+ if (child->parent ==
+ &child->ctx->activeDownloads)
+ return NULL;
+ else
+ return child->parent;
+}
+
+/**
* Start to download a file or directory recursively.
*
* @return OK on success (at least we started with it),
@@ -443,66 +549,19 @@
unsigned int anonymityLevel,
const struct ECRS_URI * uri,
const char * dirname) {
- GNUNET_ASSERT(dirname != NULL);
- return startDownload(ctx,
- anonymityLevel,
- uri,
- dirname,
- YES,
- NULL);
-}
-
-/**
- * Abort a recursive download (internal function).
- *
- * Do NOT call cleanupFSUIThreadList in here -- this
- * function maybe called recursively!
- *
- * @return OK on success, SYSERR if no such download is
- * pending
- */
-static int stopDownloadAll(struct FSUI_Context * ctx,
- const struct ECRS_URI * uri,
- const char * dirname) {
- FSUI_DownloadList * dl;
- int i;
-
- GNUNET_ASSERT(dirname != NULL);
- dl = ctx->activeDownloads;
- while (dl != NULL) {
- if ( (0 == strcmp(dirname,
- dl->filename)) &&
- (ECRS_equalsUri(uri,
- dl->uri)) ) {
- dl->signalTerminate = YES;
- for (i=0;i<dl->completedDownloadsCount;i++)
- FSUI_stopDownloadAll(ctx,
- dl->completedDownloads[i],
- dirname);
- return OK;
- }
- dl = dl->next;
- }
- return SYSERR;
-}
-
-/**
- * Abort a recursive download.
- *
- * @return OK on success, SYSERR if no such download is
- * pending
- */
-int FSUI_stopDownloadAll(struct FSUI_Context * ctx,
- const struct ECRS_URI * uri,
- const char * dirname) {
int ret;
GNUNET_ASSERT(dirname != NULL);
+ GNUNET_ASSERT(ctx != NULL);
MUTEX_LOCK(&ctx->lock);
- ret = stopDownloadAll(ctx, uri, dirname);
+ ret = startDownload(ctx,
+ anonymityLevel,
+ uri,
+ dirname,
+ YES,
+ &ctx->activeDownloads);
MUTEX_UNLOCK(&ctx->lock);
- cleanupFSUIThreadList(ctx);
return ret;
}
-
+
/* end of download.c */
Modified: GNUnet/src/applications/fs/fsui/fsui.c
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/fsui.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -62,20 +62,24 @@
}
/**
- * (Recursively) read a download list from the
- * given fd.
+ * (Recursively) read a download list from the given fd. The returned
+ * pointer is expected to be integrated into the tree either as a next
+ * or child pointer such that the given parent becomes the parent of the
+ * returned node.
*
* @return NULL on error AND on read of empty
* list (these two cannot be distinguished)
*/
static FSUI_DownloadList * readDownloadList(int fd,
- FSUI_Context * ctx) {
+ FSUI_Context * ctx,
+ FSUI_DownloadList * parent) {
char zaro;
static FSUI_DownloadList * ret;
unsigned int big;
unsigned long long bigl;
int i;
+ GNUNET_ASSERT(ctx != NULL);
if (1 != READ(fd, &zaro, sizeof(char)))
return NULL;
if (zaro == '\0')
@@ -84,11 +88,12 @@
ret->ctx = ctx;
ret->signalTerminate
- = NO;
+ = SYSERR;
READINT(ret->is_recursive);
READINT(ret->is_directory);
READINT(ret->anonymityLevel);
READINT(ret->completedDownloadsCount);
+ READINT(ret->finished);
READINT(big);
ret->filename = MALLOC(big+1);
if (big != READ(fd, ret->filename, big))
@@ -113,22 +118,14 @@
}
/* FIXME: check if URIs were
all read successfully! */
-
+ ret->parent = parent;
+ ret->signalTerminate = SYSERR;
ret->next = readDownloadList(fd,
- ctx);
- if (ret->next != NULL)
- ret->next->parent = ret;
- ret->subDownloads = readDownloadList(fd,
- ctx);
- ret->subDownloadsNext = readDownloadList(fd,
- ctx);
-
- /* start download thread! */
- if (0 != PTHREAD_CREATE(&ret->handle,
- (PThreadMain)&downloadThread,
- ret,
- 16 * 1024))
- DIE_STRERROR("pthread_create");
+ ctx,
+ parent);
+ ret->child = readDownloadList(fd,
+ ctx,
+ ret);
return ret;
ERR:
FREE(ret);
@@ -182,6 +179,7 @@
WRITEINT(fd, list->is_directory);
WRITEINT(fd, list->anonymityLevel);
WRITEINT(fd, list->completedDownloadsCount);
+ WRITEINT(fd, list->finished);
WRITEINT(fd, strlen(list->filename));
WRITE(fd,
list->filename,
@@ -196,9 +194,7 @@
writeDownloadList(fd,
list->next);
writeDownloadList(fd,
- list->subDownloads);
- writeDownloadList(fd,
- list->subDownloadsNext);
+ list->child);
}
/**
@@ -268,6 +264,19 @@
writeURI(fd, fi->uri);
}
+static void updateDownloadThreads(void * c) {
+ FSUI_Context * ctx = c;
+ FSUI_DownloadList * dpos;
+
+ MUTEX_LOCK(&ctx->lock);
+ dpos = ctx->activeDownloads.child;
+ while (dpos != NULL) {
+ updateDownloadThread(dpos);
+ dpos = dpos->next;
+ }
+ MUTEX_UNLOCK(&ctx->lock);
+}
+
/**
* Start FSUI manager. Use the given progress callback to notify the
* UI about events. Start processing pending activities that were
@@ -290,6 +299,10 @@
ret = MALLOC(sizeof(FSUI_Context));
memset(ret, 0, sizeof(FSUI_Context));
+ ret->activeDownloads.signalTerminate
+ = SYSERR;
+ ret->activeDownloads.ctx
+ = ret;
gh = getFileName("GNUNET",
"GNUNET_HOME",
"You must specify a directory for "
@@ -486,9 +499,13 @@
ret->activeSearches
= list;
}
- ret->activeDownloads
+ memset(&ret->activeDownloads,
+ 0,
+ sizeof(FSUI_DownloadList));
+ ret->activeDownloads.child
= readDownloadList(fd,
- ret);
+ ret,
+ &ret->activeDownloads);
/* success, read complete! */
goto END;
@@ -533,36 +550,18 @@
MUTEX_CREATE_RECURSIVE(&ret->lock);
ret->ecb = cb;
ret->ecbClosure = closure;
-
+ ret->threadPoolSize = getConfigurationInt("FS",
+ "POOL");
+ if (ret->threadPoolSize == 0)
+ ret->threadPoolSize = 32;
+ ret->activeDownloadThreads = 0;
+ addCronJob(&updateDownloadThreads,
+ 0,
+ 2 * cronSECONDS,
+ ret);
return ret;
}
-static void freeDownloadList(FSUI_DownloadList * list) {
- FSUI_DownloadList * dpos;
- int i;
- void * unused;
-
- while (list != NULL) {
- dpos = list;
- list = dpos->next;
- freeDownloadList(dpos->subDownloads);
- freeDownloadList(dpos->subDownloadsNext);
- dpos->signalTerminate = YES;
- if (dpos->threadStarted == YES) {
- PTHREAD_JOIN(&dpos->handle, &unused);
- dpos->threadStarted = NO;
- }
- ECRS_freeUri(dpos->uri);
- FREE(dpos->filename);
- for (i=dpos->completedDownloadsCount-1;i>=0;i--)
- ECRS_freeUri(dpos->completedDownloads[i]);
- GROW(dpos->completedDownloads,
- dpos->completedDownloadsCount,
- 0);
- FREE(dpos);
- }
-}
-
/**
* Stop all processes under FSUI control (serialize state, continue
* later if possible).
@@ -570,6 +569,7 @@
void FSUI_stop(struct FSUI_Context * ctx) {
FSUI_ThreadList * tpos;
FSUI_SearchList * spos;
+ FSUI_DownloadList * dpos;
void * unused;
int i;
int fd;
@@ -578,6 +578,22 @@
LOG(LOG_INFO,
"FSUI shutdown. This may take a while.\n");
FSUI_publishCollectionNow(ctx);
+
+ suspendCron();
+ delCronJob(&updateDownloadThreads,
+ 5 * cronSECONDS,
+ ctx);
+ resumeCron();
+ /* first, stop all download threads
+ by reducing the thread pool size to 0 */
+ ctx->threadPoolSize = 0;
+ dpos = ctx->activeDownloads.child;
+ while (dpos != NULL) {
+ updateDownloadThread(dpos);
+ dpos = dpos->next;
+ }
+
+ /* then, wait for all modal threads to complete */
while (ctx->activeThreads != NULL) {
tpos = ctx->activeThreads;
ctx->activeThreads = tpos->next;
@@ -585,6 +601,7 @@
FREE(tpos);
}
+ /* next, serialize all of the FSUI state */
if (ctx->ipc != NULL) {
fd = fileopen(ctx->name,
O_CREAT|O_TRUNC|O_WRONLY,
@@ -663,6 +680,7 @@
}
}
+
ECRS_freeUri(spos->uri);
for (i=spos->sizeResultsReceived-1;i>=0;i--) {
ECRS_FileInfo * fi;
@@ -696,12 +714,14 @@
&big,
sizeof(unsigned int));
writeDownloadList(fd,
- ctx->activeDownloads);
+ ctx->activeDownloads.child);
}
- freeDownloadList(ctx->activeDownloads);
- ctx->activeDownloads = NULL;
if (fd != -1)
CLOSE(fd);
+
+ /* finally, free all (remaining) FSUI data */
+ while (ctx->activeDownloads.child != NULL)
+ freeDownloadList(ctx->activeDownloads.child);
if (ctx->ipc != NULL) {
IPC_SEMAPHORE_UP(ctx->ipc);
IPC_SEMAPHORE_FREE(ctx->ipc);
@@ -716,16 +736,15 @@
/* *************** internal helper functions *********** */
-
+/**
+ * The idea for this function is to clean up
+ * the FSUI structs by freeing up dead entries.
+ */
void cleanupFSUIThreadList(FSUI_Context * ctx) {
FSUI_ThreadList * pos;
FSUI_ThreadList * tmp;
FSUI_ThreadList * prev;
- FSUI_DownloadList * dpos;
- FSUI_DownloadList * dprev;
- FSUI_DownloadList * dtmp;
void * unused;
- int i;
prev = NULL;
MUTEX_LOCK(&ctx->lock);
@@ -746,41 +765,6 @@
pos = pos->next;
}
}
-
-#if 0
- /* FIXME: severely broken:
- - concurrency issue with FSUI_stop,
- - does not take tree structure into
- account (activeDownloads is more
- than just a linked list!)
- */
- dpos = ctx->activeDownloads;
- dprev = NULL;
- while (dpos != NULL) {
- if ( (YES == dpos->signalTerminate) &&
- (NO == PTHREAD_SELF_TEST(&dpos->handle)) ) {
- PTHREAD_JOIN(&dpos->handle,
- &unused);
- dtmp = dpos->next;
- ECRS_freeUri(dpos->uri);
- FREE(dpos->filename);
- for (i=0;i<dpos->completedDownloadsCount;i++)
- ECRS_freeUri(dpos->completedDownloads[i]);
- GROW(dpos->completedDownloads,
- dpos->completedDownloadsCount,
- 0);
- FREE(dpos);
- if (dprev != NULL)
- dprev->next = dtmp;
- else
- ctx->activeDownloads = dtmp;
- dpos = dtmp;
- } else {
- dprev = dpos;
- dpos = dpos->next;
- }
- }
-#endif
MUTEX_UNLOCK(&ctx->lock);
}
Modified: GNUnet/src/applications/fs/fsui/fsui.h
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.h 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/fsui.h 2005-06-14 16:58:05 UTC (rev
925)
@@ -34,12 +34,18 @@
* Linked list of FSUI threads.
*/
typedef struct FSUI_ThreadList {
+
+ /**
+ * FSUI threads are kept in a simple
+ * linked list
+ */
struct FSUI_ThreadList * next;
/**
* Handle to a thread.
*/
PTHREAD_T handle;
+
/**
* Flag that indicates if it is safe (i.e.
* non-blocking) to call join on the handle.
@@ -52,15 +58,18 @@
* Track record for a given result.
*/
typedef struct {
+
/**
* For how many keys (hash of keyword) did we
* get this result?
*/
unsigned int matchingKeyCount;
+
/**
* What are these keys?
*/
HashCode512 * matchingKeys;
+
/**
* What info do we have about this result?
*/
@@ -71,8 +80,15 @@
* @brief list of active searches
*/
typedef struct FSUI_SearchList {
+
+ /**
+ * Searches are kept in a simple linked list.
+ */
struct FSUI_SearchList * next;
+ /**
+ * Context for this search
+ */
struct FSUI_Context * ctx;
/**
@@ -91,6 +107,9 @@
*/
struct ECRS_URI * uri;
+ /**
+ * Desired anonymity level for this search
+ */
unsigned int anonymityLevel;
/**
@@ -99,6 +118,9 @@
*/
unsigned int numberOfURIKeys;
+ /**
+ * Size of the resultsReceived array
+ */
unsigned int sizeResultsReceived;
/**
@@ -138,33 +160,43 @@
* list of sub-downloads that are currently
* going on in parallel.
*/
- struct FSUI_DownloadList * subDownloads;
+ struct FSUI_DownloadList * child;
/**
- * Next entry in the linked list of subdownloads.
+ * FSUI context for this download.
*/
- struct FSUI_DownloadList * subDownloadsNext;
+ struct FSUI_Context * ctx;
/**
- * FSUI context for this download.
+ * Set this to YES to signal the download thread that
+ * termination is desired. Then join on handle.
+ * Set to NO if thread is running. Set to SYSERR
+ * if no thread has been assigned to this download
+ * at the moment.
*/
- struct FSUI_Context * ctx;
+ int signalTerminate;
/**
- * Handle to the thread which performs the download.
+ * Is the download of this file finished (not necessarily
+ * transitively for directories, just the directory/file
+ * itself).
*/
+ int finished;
+
+ /**
+ * Currently assigned thread (if any).
+ */
PTHREAD_T handle;
/**
- * Set this to YES to signal the download thread that
- * termination is desired. Then join on handle.
+ * How many bytes is this download in total
+ * (including files in directory).
*/
- int signalTerminate;
-
- int threadStarted;
-
unsigned long long total;
+ /**
+ * How many bytes have been retrieved so far?
+ */
unsigned long long completed;
/**
@@ -183,7 +215,9 @@
int is_recursive;
/**
- * When did the download start?
+ * When did the download start? Note that if a download is resumed,
+ * this time is set such that the total time is accurate, not the
+ * absolute start time.
*/
cron_t startTime;
@@ -226,8 +260,16 @@
*/
typedef struct FSUI_Context {
+ /**
+ * IPC semaphore used to ensure mutual exclusion
+ * between different processes of the same name
+ * that all use resume.
+ */
IPC_Semaphore * ipc;
+ /**
+ * Name of the tool using FSUI (used for resume).
+ */
char * name;
/**
@@ -262,20 +304,48 @@
FSUI_SearchList * activeSearches;
/**
- * List of active downloads
+ * Root of the tree of downloads. On shutdown,
+ * FSUI must abort each of these downloads.
*/
- FSUI_DownloadList * activeDownloads;
+ FSUI_DownloadList activeDownloads;
+ /**
+ * Target size of the thread pool for parallel
+ * downloads.
+ */
+ unsigned int threadPoolSize;
+
+ /**
+ * Number of download threads that are
+ * currently active.
+ */
+ unsigned int activeDownloadThreads;
+
} FSUI_Context;
/**
+ * Starts or stops download threads in accordance with thread pool
+ * size and active downloads. Call only while holding FSUI lock (or
+ * during start/stop).
+ *
+ * @return YES if change done that may require re-trying
+ */
+int updateDownloadThread(FSUI_DownloadList * list);
+
+/**
+ * Free the subtree (assumes all threads have already been stopped and
+ * that the FSUI lock is either held or that we are in FSUI stop!).
+ */
+void freeDownloadList(FSUI_DownloadList * list);
+
+/**
* Cleanup the FSUI context (removes dead entries from
- * activeThreads / activeSearches).
+ * activeThreads / activeSearches / activeDownloads).
*/
void cleanupFSUIThreadList(FSUI_Context * ctx);
-/* from download.c */
+/* FOR RESUME: from download.c */
/**
* Thread that downloads a file.
*/
@@ -283,7 +353,7 @@
/* from search.c */
/**
- * Thread that searches for data.
+ * FOR RESUME: Thread that searches for data.
*/
void * searchThread(FSUI_SearchList * pos);
Modified: GNUnet/src/applications/fs/fsui/search.c
===================================================================
--- GNUnet/src/applications/fs/fsui/search.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/search.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -46,7 +46,7 @@
pos->resultsReceived[pos->sizeResultsReceived-1].meta
= ECRS_dupMetaData(fi->meta);
- event.type = search_result;
+ event.type = FSUI_search_result;
event.data.SearchResult.fi = *fi;
event.data.SearchResult.searchURI = pos->uri;
pos->ctx->ecb(pos->ctx->ecbClosure,
Modified: GNUnet/src/applications/fs/fsui/unindex.c
===================================================================
--- GNUnet/src/applications/fs/fsui/unindex.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/unindex.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -49,7 +49,7 @@
UnindexThreadClosure * utc) {
FSUI_Event event;
- event.type = unindex_progress;
+ event.type = FSUI_unindex_progress;
event.data.UnindexProgress.completed = completedBytes;
event.data.UnindexProgress.total = totalBytes;
event.data.UnindexProgress.filename = utc->filename;
@@ -74,12 +74,12 @@
NULL,
NULL);
if (ret == OK) {
- event.type = unindex_complete;
+ event.type = FSUI_unindex_complete;
event.data.UnindexComplete.total = getFileSize(utc->filename);
event.data.UnindexComplete.filename = utc->filename;
event.data.UnindexComplete.start_time = utc->start_time;
} else {
- event.type = unindex_error;
+ event.type = FSUI_unindex_error;
event.data.message = _("Unindex failed.\n");
}
FREE(utc->filename);
Modified: GNUnet/src/applications/fs/fsui/upload.c
===================================================================
--- GNUnet/src/applications/fs/fsui/upload.c 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/applications/fs/fsui/upload.c 2005-06-14 16:58:05 UTC (rev
925)
@@ -73,7 +73,7 @@
cron_t now;
cronTime(&now);
- event.type = upload_progress;
+ event.type = FSUI_upload_progress;
event.data.UploadProgress.completed = completedBytes;
event.data.UploadProgress.total = totalBytes;
event.data.UploadProgress.filename = utc->filename;
@@ -160,7 +160,7 @@
NULL,
uri);
if (ret == OK) {
- event.type = upload_complete;
+ event.type = FSUI_upload_complete;
event.data.UploadComplete.total = utc->main_total;
event.data.UploadComplete.filename = STRDUP(dirName);
event.data.UploadComplete.uri = *uri;
@@ -219,7 +219,7 @@
NULL,
NULL,
&uri);
- event.type = upload_complete;
+ event.type = FSUI_upload_complete;
event.data.UploadComplete.total = utc->main_total;
event.data.UploadComplete.filename = utc->filename;
event.data.UploadComplete.uri = uri;
@@ -336,7 +336,7 @@
NULL,
&uri);
if (ret == OK) {
- event.type = upload_complete;
+ event.type = FSUI_upload_complete;
event.data.UploadComplete.total = utc->main_total;
event.data.UploadComplete.filename = utc->filename;
event.data.UploadComplete.uri = uri;
@@ -345,7 +345,7 @@
event.data.UploadComplete.is_recursive = NO;
event.data.UploadComplete.main_filename = utc->main_filename;
} else {
- event.type = upload_error;
+ event.type = FSUI_upload_error;
event.data.message = _("Upload failed.\n");
}
utc->ctx->ecb(utc->ctx->ecbClosure,
@@ -384,14 +384,14 @@
0);
if (ret != OK) {
- event.type = upload_error;
+ event.type = FSUI_upload_error;
event.data.message = _("Upload failed.\n");
utc->ctx->ecb(utc->ctx->ecbClosure,
&event);
} /* for success, uploadDirectory sends event already! */
utc->filename = NULL;
} else {
- event.type = upload_error;
+ event.type = FSUI_upload_error;
event.data.message = _("Cannot upload directory without using
recursion.\n");
utc->ctx->ecb(utc->ctx->ecbClosure,
&event);
Modified: GNUnet/src/applications/fs/tools/gnunet-download.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-download.c 2005-06-13 20:56:27 UTC
(rev 924)
+++ GNUnet/src/applications/fs/tools/gnunet-download.c 2005-06-14 16:58:05 UTC
(rev 925)
@@ -149,7 +149,7 @@
int * ok = okVal;
switch (event->type) {
- case download_progress:
+ case FSUI_download_progress:
if (YES == testConfigurationString("GNUNET-DOWNLOAD",
"VERBOSE",
"YES")) {
@@ -162,22 +162,38 @@
printf("\r");
}
break;
- case download_error:
+ case FSUI_download_aborted:
+ if (FSUI_getDownloadParent(event->data.DownloadError.pos) == NULL) {
+ /* top-download aborted */
+ printf(_("Error downloading: %s\n"),
+ event->data.DownloadError.message);
+ *ok = SYSERR;
+ SEMAPHORE_UP(signalFinished);
+ } else {
+ /* child aborted, maybe FSUI thread
+ policy, ignore? How can this
+ happen anyway with gnunet-download? */
+ }
+ break;
+ case FSUI_download_error:
printf(_("Error downloading: %s\n"),
- event->data.message);
+ event->data.DownloadError.message);
*ok = SYSERR;
SEMAPHORE_UP(signalFinished);
break;
- case download_complete:
- printf(_("\nDownload of file '%s' complete. Speed was %8.3f kilobyte per
second.\n"),
- event->data.DownloadProgress.filename,
- (event->data.DownloadProgress.completed/1024.0) /
- (((double)(cronTime(NULL)-(event->data.DownloadProgress.start_time -
1)))
- / (double)cronSECONDS) );
- if (ECRS_equalsUri(event->data.DownloadProgress.main_uri,
- event->data.DownloadProgress.uri) ) {
- *ok = OK;
- SEMAPHORE_UP(signalFinished);
+ case FSUI_download_complete:
+ if ( (event->data.DownloadProgress.completed ==
+ event->data.DownloadProgress.total) ) {
+ printf(_("\nDownload of file '%s' complete. Speed was %8.3f kilobyte
per second.\n"),
+ event->data.DownloadProgress.filename,
+ (event->data.DownloadProgress.completed/1024.0) /
+ (((double)(cronTime(NULL)-(event->data.DownloadProgress.start_time
- 1)))
+ / (double)cronSECONDS) );
+ if (ECRS_equalsUri(event->data.DownloadProgress.main_uri,
+ event->data.DownloadProgress.uri)) {
+ *ok = OK;
+ SEMAPHORE_UP(signalFinished);
+ }
}
break;
default:
Modified: GNUnet/src/applications/fs/tools/gnunet-insert.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-insert.c 2005-06-13 20:56:27 UTC
(rev 924)
+++ GNUnet/src/applications/fs/tools/gnunet-insert.c 2005-06-14 16:58:05 UTC
(rev 925)
@@ -121,7 +121,7 @@
char * fstring;
switch(event->type) {
- case upload_progress:
+ case FSUI_upload_progress:
if (*verboselevel == YES) {
delta = event->data.UploadProgress.eta - cronTime(NULL);
PRINTF(
@@ -132,7 +132,7 @@
printf("\r");
}
break;
- case upload_complete:
+ case FSUI_upload_complete:
if (*verboselevel == YES) {
delta = event->data.UploadComplete.eta -
event->data.UploadComplete.start_time;
PRINTF(
@@ -157,7 +157,7 @@
}
break;
- case upload_error:
+ case FSUI_upload_error:
printf(_("\nError uploading file: %s\n"),
event->data.message);
errorCode = 1;
Modified: GNUnet/src/applications/fs/tools/gnunet-search.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-search.c 2005-06-13 20:56:27 UTC
(rev 924)
+++ GNUnet/src/applications/fs/tools/gnunet-search.c 2005-06-14 16:58:05 UTC
(rev 925)
@@ -58,7 +58,7 @@
char * uri;
char * filename;
- if (event->type != search_result)
+ if (event->type != FSUI_search_result)
return;
/* retain URIs for possible directory dump later */
Modified: GNUnet/src/applications/fs/tools/gnunet-unindex.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-unindex.c 2005-06-13 20:56:27 UTC
(rev 924)
+++ GNUnet/src/applications/fs/tools/gnunet-unindex.c 2005-06-14 16:58:05 UTC
(rev 925)
@@ -44,7 +44,7 @@
unsigned long long delta;
switch(event->type) {
- case unindex_progress:
+ case FSUI_unindex_progress:
if (*verboselevel == YES) {
delta = event->data.UploadProgress.eta - cronTime(NULL);
PRINTF(_("%16llu of %16llu bytes unindexed (estimating %llu seconds to
completion) "),
@@ -54,7 +54,7 @@
printf("\r");
}
break;
- case unindex_complete:
+ case FSUI_unindex_complete:
if (*verboselevel == YES) {
delta = event->data.UploadComplete.eta -
event->data.UploadComplete.start_time;
PRINTF(
@@ -67,7 +67,7 @@
: (double) (event->data.UploadComplete.total / 1024.0 * cronSECONDS /
delta));
}
break;
- case unindex_error:
+ case FSUI_unindex_error:
printf(_("\nError unindexing file: %s\n"),
event->data.message);
errorCode = 1;
Modified: GNUnet/src/include/gnunet_fsui_lib.h
===================================================================
--- GNUnet/src/include/gnunet_fsui_lib.h 2005-06-13 20:56:27 UTC (rev
924)
+++ GNUnet/src/include/gnunet_fsui_lib.h 2005-06-14 16:58:05 UTC (rev
925)
@@ -65,31 +65,46 @@
#include "gnunet_ecrs_lib.h"
/**
+ * Entry representing an FSUI download. FSUI downloads form a tree
+ * (for properly representing recursive downloads) with an invisible
+ * root (for multiple parallel downloads).
+ *
+ * FSUI hands out references of this type to allow clients to access
+ * information about active downloads.
+ *
+ * Structs of this type MUST NOT be stored in anything but local
+ * variables (!) by FSUI clients. This will ensure that the
+ * references are always valid.
+ */
+struct FSUI_DownloadList;
+
+/**
* @brief types of FSUI events.
*/
enum FSUI_EventType {
/**
* We found a new search result.
*/
- search_result,
- search_error,
- download_progress,
- download_complete,
- download_error,
- upload_progress,
- upload_complete,
- upload_error,
- unindex_progress,
- unindex_complete,
- unindex_error,
+ FSUI_search_result,
+ FSUI_search_error,
+ FSUI_download_progress,
+ FSUI_download_complete,
+ FSUI_download_aborted,
+ FSUI_download_error,
+ FSUI_upload_progress,
+ FSUI_upload_complete,
+ FSUI_upload_error,
+ FSUI_unindex_progress,
+ FSUI_unindex_complete,
+ FSUI_unindex_error,
/**
* Connection status with gnunetd changed.
*/
- gnunetd_connected,
+ FSUI_gnunetd_connected,
/**
* Connection status with gnunetd changed.
*/
- gnunetd_disconnected,
+ FSUI_gnunetd_disconnected,
};
/**
@@ -165,9 +180,30 @@
* main URI? (otherwise equal to uri);
*/
struct ECRS_URI * main_uri;
+ /**
+ * What file in the download tree are we
+ * refering to?
+ */
+ struct FSUI_DownloadList * pos;
} DownloadProgress;
+ /**
+ * DownloadError is used for both
+ * download_aborted and download_error
+ * message types.
+ */
struct {
/**
+ * Error message.
+ */
+ const char * message;
+ /**
+ * What file in the download tree are we
+ * refering to?
+ */
+ struct FSUI_DownloadList * pos;
+ } DownloadError;
+ struct {
+ /**
* How far are we? (for the current file)
*/
unsigned long long completed;
@@ -266,15 +302,13 @@
struct FSUI_Context;
/**
- * Generic callback for all kinds of FSUI progress
- * and error messages. This function will be called
- * for download progress, download completion, upload
- * progress and completion, search results, etc.
+ * Generic callback for all kinds of FSUI progress and error messages.
+ * This function will be called for download progress, download
+ * completion, upload progress and completion, search results, etc.
*
- * The details of the argument format are yet to be
- * defined. What FSUI guarantees is that only one
- * thread at a time will call the callback (so it
- * need not be re-entrant).
+ * The details of the argument format are yet to be defined. What
+ * FSUI guarantees is that only one thread at a time will call the
+ * callback (so it need not be re-entrant).
*/
typedef void (*FSUI_EventCallback)(void * cls,
const FSUI_Event * event);
@@ -323,9 +357,12 @@
/**
* Iterator over active downloads.
*
+ * @param pos What file in the download tree are we
+ * refering to?
* @return OK to continue iteration, SYSERR to abort
*/
typedef int (*FSUI_DownloadIterator)(void * cls,
+ const struct FSUI_DownloadList * pos,
const char * filename,
const struct ECRS_URI * uri,
unsigned long long filesize,
@@ -388,6 +425,7 @@
* if keywords is not legal (i.e. empty).
*/
struct ECRS_URI * FSUI_parseCharKeywordURI(const char * keywords); /* helper.c
*/
+
/**
* Create an ECRS URI from a user-supplied command line of keywords.
* The command line may contain the reserved word 'AND' to create a
@@ -447,7 +485,10 @@
const char * filename); /* download.c */
/**
- * Abort a download.
+ * Abort a download. If the URI was for a recursive
+ * download, all sub-downloads will also be aborted.
+ * Cannot be used to terminate a single file download
+ * that is part of a recursive download.
*
* @return SYSERR if no such download is pending
*/
@@ -460,12 +501,23 @@
* downloads, FSUI clients should listen closely
* to the FSUI_EventCallback to not miss completion
* events.
+ *
+ * @param root subtree to iterate over, use
+ * NULL for all top-level downloads
*/
int FSUI_listDownloads(struct FSUI_Context * ctx,
+ const struct FSUI_DownloadList * root,
FSUI_DownloadIterator iter,
void * closure); /* download.c */
/**
+ * Get parent of active download.
+ * @return NULL if there is no parent
+ */
+const struct FSUI_DownloadList *
+FSUI_getDownloadParent(const struct FSUI_DownloadList * child); /* download.c
*/
+
+/**
* Start uploading a file. Note that an upload cannot be stopped once
* started (not necessary anyway), but it can fail. The function also
* automatically the uploaded file in the global keyword space under
@@ -526,16 +578,6 @@
const struct ECRS_URI * uri,
const char * dirname); /* download.c */
-/**
- * Abort a download.
- *
- * @return OK on success, SYSERR if no such download is
- * pending
- */
-int FSUI_stopDownloadAll(struct FSUI_Context * ctx,
- const struct ECRS_URI * uri,
- const char * dirname); /* download.c */
-
/* ******************** collections API **************** */
/**
@@ -567,31 +609,27 @@
* changed since the last publication. If we are currently not
* collecting, this function does nothing.
*
- * Note that clients typically don't have to call this
- * function explicitly. FSUI will call the function on
- * exit (for sporadically updated collections), on any
- * change to the collection (for immediately updated
- * content) or when the publication time has arrived
- * (for periodically updated collections).
+ * Note that clients typically don't have to call this function
+ * explicitly. FSUI will call the function on exit (for sporadically
+ * updated collections), on any change to the collection (for
+ * immediately updated content) or when the publication time has
+ * arrived (for periodically updated collections).
*
- * However, clients may want to call this function if
- * explicit publication of an update at another
- * time is desired.
+ * However, clients may want to call this function if explicit
+ * publication of an update at another time is desired.
*/
void FSUI_publishCollectionNow(struct FSUI_Context * ctx);
/**
- * If we are currently building a collection, publish
- * the given file information in that collection.
- * If we are currently not collecting, this function
- * does nothing.
+ * If we are currently building a collection, publish the given file
+ * information in that collection. If we are currently not
+ * collecting, this function does nothing.
*
- * Note that clients typically don't have to call this
- * function explicitly -- by using the FSUI library it
- * should be called automatically by FSUI code whenever
- * needed. However, the function maybe useful if you're
- * inserting files using libECRS directly or need other
- * ways to explicitly extend a collection.
+ * Note that clients typically don't have to call this function
+ * explicitly -- by using the FSUI library it should be called
+ * automatically by FSUI code whenever needed. However, the function
+ * maybe useful if you're inserting files using libECRS directly or
+ * need other ways to explicitly extend a collection.
*/
void FSUI_publishToCollection(struct FSUI_Context * ctx,
const ECRS_FileInfo * fi);
@@ -619,9 +657,8 @@
struct ECRS_URI ** root); /* namespace_info.c */
/**
- * Delete a local namespace. Only prevents future insertions
- * into the namespace, does not delete any content from
- * the network!
+ * Delete a local namespace. Only prevents future insertions into the
+ * namespace, does not delete any content from the network!
*
* @return OK on success, SYSERR on error
*/
@@ -635,9 +672,9 @@
int delta); /* namespace_info.c */
/**
- * Add a namespace to the set of known namespaces.
- * For all namespace advertisements that we discover
- * FSUI should automatically call this function.
+ * Add a namespace to the set of known namespaces. For all namespace
+ * advertisements that we discover FSUI should automatically call this
+ * function.
*
* @param ns the namespace identifier
*/
@@ -724,7 +761,6 @@
*/
void FSUI_trackURIS(int onOff); /* file_info.c */
-
/**
* Get the FSUI URI tracking status.
*
@@ -733,10 +769,9 @@
int FSUI_trackStatus(void); /* file_info.c */
/**
- * Makes a URI available for directory building.
- * This function is automatically called by all FSUI
- * functions and only in the interface for clients that
- * call ECRS directly.
+ * Makes a URI available for directory building. This function is
+ * automatically called by all FSUI functions and only in the
+ * interface for clients that call ECRS directly.
*/
void FSUI_trackURI(const ECRS_FileInfo * fi); /* file_info.c */
Modified: GNUnet/todo
===================================================================
--- GNUnet/todo 2005-06-13 20:56:27 UTC (rev 924)
+++ GNUnet/todo 2005-06-14 16:58:05 UTC (rev 925)
@@ -1,12 +1,16 @@
0.7.0pre3:
-- gnunet-gtk (debug)
+- gnunet-gtk:
+ * make directories work [ CG ]
+- FSUI:
+ * make (recursive) downloads work (test/debug) [ CG ]
+- GAP:
+ * fix Nils' assertion failure/bug [ CG ]
- gnunet-setup: [Nils]
* gconfig: fix focus changes
* wizards: restrict user & service creation to platforms
known to be working.
0.7.0 [6'05?] (aka "compatibility? what's that?"):
-- FSUI: recursive directory download crashes (i.e. on exit)
- Missing Features:
* resolve "FIXME 0.7": only sqlite magic factor missing! [Nils]
* #593 (gnunet-setup): php-ification for i18n [ Nils ]
@@ -33,8 +37,6 @@
0.7.1 (aka "stabilization"):
- Optimizations:
* spread out scanning done in topology_*.c?
- * fsui download: limit parallelism (currently unlimited, old gnunet-download
allowed
- user to specify maximum amount of parallelism) [ tricky ]
- gnunet-chat
- DHT:
* make dht tests work
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r925 - in GNUnet: . contrib src/applications/fs/ecrs src/applications/fs/fsui src/applications/fs/tools src/include,
grothoff <=