[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r3482 - in GNUnet/src: applications/fs/fsui applications/fs
From: |
grothoff |
Subject: |
[GNUnet-SVN] r3482 - in GNUnet/src: applications/fs/fsui applications/fs/tools include |
Date: |
Thu, 12 Oct 2006 20:09:50 -0700 (PDT) |
Author: grothoff
Date: 2006-10-12 20:09:42 -0700 (Thu, 12 Oct 2006)
New Revision: 3482
Added:
GNUnet/src/applications/fs/fsui/deserialize.c
GNUnet/src/applications/fs/fsui/serialize.c
Modified:
GNUnet/src/applications/fs/fsui/Makefile.am
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-unindex.c
GNUnet/src/include/gnunet_fsui_lib.h
Log:
fsui hacking
Modified: GNUnet/src/applications/fs/fsui/Makefile.am
===================================================================
--- GNUnet/src/applications/fs/fsui/Makefile.am 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/Makefile.am 2006-10-13 03:09:42 UTC (rev
3482)
@@ -6,9 +6,11 @@
noinst_PROGRAMS = fsui-loader
libgnunetfsui_la_SOURCES = \
+ deserialize.c \
download.c \
fsui.c fsui.h \
search.c \
+ serialize.c \
unindex.c \
upload.c
libgnunetfsui_la_LIBADD = \
Added: GNUnet/src/applications/fs/fsui/deserialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/deserialize.c 2006-10-12 20:51:47 UTC
(rev 3481)
+++ GNUnet/src/applications/fs/fsui/deserialize.c 2006-10-13 03:09:42 UTC
(rev 3482)
@@ -0,0 +1,527 @@
+/*
+ This file is part of GNUnet.
+ (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other
contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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.
+*/
+
+
+/**
+ * @file applications/fs/fsui/deserializer.c
+ * @brief FSUI functions for reading state from disk
+ * @author Christian Grothoff
+ * @see serializer.c
+ *
+ * TODO:
+ * - deserialize upload and unindex!
+ */
+
+#include "platform.h"
+#include "gnunet_fsui_lib.h"
+#include "gnunet_directories.h"
+#include "fsui.h"
+
+
+static int read_int(int fd,
+ int * val) {
+ int big;
+
+ if (sizeof(int) != READ(fd, &big, sizeof(int))) \
+ return SYSERR; \
+ *val = ntohl(big);
+ return OK;
+}
+
+#define READINT(a) if (OK != read_int(fd, (int*) a)) return SYSERR;
+
+static int read_long(int fd,
+ long long * val) {
+ long long big;
+
+ if (sizeof(long long) != READ(fd, &big, sizeof(long long))) \
+ return SYSERR; \
+ *val = ntohll(big);
+ return OK;
+}
+
+#define READLONG(a) if (OK != read_long(fd, (long long*) a)) return SYSERR;
+
+static struct ECRS_URI * read_uri(struct GE_Context * ectx,
+ int fd) {
+ char * buf;
+ struct ECRS_URI * ret;
+ unsigned int size;
+
+ if (OK != read_int(fd, (int*) &size))
+ return NULL;
+ buf = MALLOC(size+1);
+ buf[size] = '\0';
+ if (size != READ(fd,
+ buf,
+ size)) {
+ FREE(buf);
+ return NULL;
+ }
+ ret = ECRS_stringToUri(ectx, buf);
+ FREE(buf);
+ return ret;
+}
+
+#define READURI(u) if (NULL == (u = read_uri(ectx, fd))) return SYSERR;
+
+static char * read_string(int fd,
+ unsigned int maxLen) {
+ char * buf;
+ unsigned int big;
+
+ if (OK != read_int(fd, (int*) &big))
+ return NULL;
+ if (big > maxLen)
+ return NULL;
+ buf = MALLOC(big + 1);
+ buf[big] = '\0';
+ if (big != READ(fd, buf, big)) {
+ FREE(buf);
+ return NULL;
+ }
+ return buf;
+}
+
+static void fixState(FSUI_State * state) {
+ switch (*state) { /* try to correct errors */
+ case FSUI_ACTIVE:
+ *state = FSUI_PENDING;
+ break;
+ case FSUI_PENDING:
+ case FSUI_COMPLETED_JOINED:
+ case FSUI_ABORTED_JOINED:
+ case FSUI_ERROR_JOINED:
+ break;
+ case FSUI_ERROR:
+ *state = FSUI_ERROR_JOINED;
+ break;
+ case FSUI_ABORTED:
+ *state = FSUI_ABORTED_JOINED;
+ break;
+ case FSUI_COMPLETED:
+ *state = FSUI_COMPLETED_JOINED;
+ break;
+ default:
+ *state = FSUI_ERROR_JOINED;
+ break;
+ }
+}
+
+/**
+ * (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(struct GE_Context * ectx,
+ int fd,
+ FSUI_Context * ctx,
+ FSUI_DownloadList * parent) {
+ FSUI_DownloadList * ret;
+ unsigned int big;
+ int i;
+ int ok;
+
+ GE_ASSERT(ectx, ctx != NULL);
+ if ( (OK != read_int(fd, (int*) &big)) ||
+ (big == 0) )
+ return NULL;
+ ret = MALLOC(sizeof(FSUI_DownloadList));
+ memset(ret,
+ 0,
+ sizeof(FSUI_DownloadList));
+ ret->ctx = ctx;
+ if ( (OK != read_int(fd, (int*) &ret->state)) ||
+ (OK != read_int(fd, (int*) &ret->is_recursive)) ||
+ (OK != read_int(fd, (int*) &ret->is_directory)) ||
+ (OK != read_int(fd, (int*) &ret->anonymityLevel)) ||
+ (OK != read_int(fd, (int*) &ret->completedDownloadsCount)) ||
+ (OK != read_long(fd, (long long*) &ret->total)) ||
+ (OK != read_long(fd, (long long*) &ret->completed)) ||
+ (OK != read_long(fd, (long long*) &ret->runTime)) ||
+ (OK != read_int(fd, (int*) &big)) ||
+ (big > 1024 * 1024) ) {
+ FREE(ret);
+ return NULL;
+ }
+ fixState(&ret->state);
+ ret->filename = MALLOC(big+1);
+ ret->filename[big] = '\0';
+ if (big != READ(fd, ret->filename, big)) {
+ GE_BREAK(ectx, 0);
+ FREE(ret->filename);
+ FREE(ret);
+ return NULL;
+ }
+ if (NULL == (ret->uri = read_uri(ectx, fd))) {
+ FREE(ret->filename);
+ FREE(ret);
+ return NULL;
+ }
+ if (ret->completedDownloadsCount > 0)
+ ret->completedDownloads
+ = MALLOC(sizeof(struct ECRS_URI *) *
+ ret->completedDownloadsCount);
+ ok = YES;
+ for (i=0;i<ret->completedDownloadsCount;i++) {
+ ret->completedDownloads[i] = read_uri(ectx, fd);
+ if (ret->completedDownloads[i] == NULL)
+ ok = NO;
+ }
+ if (NO == ok) {
+ FREE(ret->filename);
+ ECRS_freeUri(ret->uri);
+ for (i=0;i<ret->completedDownloadsCount;i++) {
+ if (ret->completedDownloads[i] != NULL)
+ ECRS_freeUri(ret->completedDownloads[i]);
+ }
+ FREE(ret->completedDownloads);
+ FREE(ret);
+ return NULL;
+ }
+ ret->parent = parent;
+ ret->next = readDownloadList(ectx,
+ fd,
+ ctx,
+ parent);
+ ret->child = readDownloadList(ectx,
+ fd,
+ ctx,
+ ret);
+#if DEBUG_PERSISTENCE
+ GE_LOG(ectx,
+ GE_DEBUG | GE_REQUEST | GE_USER,
+ "FSUI persistence: restoring download `%s': (%llu, %llu)\n",
+ ret->filename,
+ ret->completed,
+ ret->total);
+#endif
+ return ret;
+}
+
+
+/**
+ * Read file info from file.
+ *
+ * @return OK on success, SYSERR on error
+ */
+static int readFileInfo(struct GE_Context * ectx,
+ int fd,
+ ECRS_FileInfo * fi) {
+ unsigned int size;
+ char * buf;
+
+ fi->meta = NULL;
+ fi->uri = NULL;
+ READINT(size);
+ if (size > 1024 * 1024) {
+ GE_BREAK(ectx, 0);
+ return SYSERR;
+ }
+ buf = MALLOC(size);
+ if (size != READ(fd,
+ buf,
+ size)) {
+ FREE(buf);
+ GE_BREAK(ectx, 0);
+ return SYSERR;
+ }
+ fi->meta = ECRS_deserializeMetaData(ectx,
+ buf,
+ size);
+ if (fi->meta == NULL) {
+ FREE(buf);
+ GE_BREAK(ectx, 0);
+ return SYSERR;
+ }
+ FREE(buf);
+
+ fi->uri
+ = read_uri(ectx, fd);
+ if (fi->uri == NULL) {
+ ECRS_freeMetaData(fi->meta);
+ fi->meta = NULL;
+ GE_BREAK(ectx, 0);
+ return SYSERR;
+ }
+ return OK;
+}
+
+static int checkMagic(int fd) {
+ char magic[8];
+
+ if (8 != READ(fd, magic, 8)) {
+ GE_BREAK(NULL, 0);
+ return SYSERR;
+ }
+ if (0 != memcmp(magic,
+ "FSUI01\n\0",
+ 8)) {
+ GE_BREAK(NULL, 0);
+ return SYSERR;
+ }
+ return OK;
+}
+
+static int readCollection(int fd,
+ struct FSUI_Context * ctx) {
+ int big;
+
+ /* deserialize collection data */
+ READINT(big);
+ if ( (big > 16 * 1024 * 1024) ||
+ (big < sizeof(unsigned int) ) ) {
+ GE_BREAK(NULL, 0);
+ return SYSERR;
+ }
+ if (big == 0) {
+ ctx->collectionData = NULL;
+ return OK;
+ }
+ ctx->collectionData
+ = MALLOC(big);
+ if (big - sizeof(unsigned int) !=
+ READ(fd,
+ &ctx->collectionData[1],
+ big - sizeof(unsigned int))) {
+ FREE(ctx->collectionData);
+ ctx->collectionData = NULL;
+ GE_BREAK(NULL, 0);
+ return SYSERR;
+ }
+ return OK;
+}
+
+static int readSearches(int fd,
+ struct FSUI_Context * ctx) {
+ int big;
+ FSUI_SearchList * list;
+ int i;
+ ResultPending * rp;
+ char * buf;
+
+ while (1) {
+ READINT(big);
+ if (big == 0)
+ return OK;
+ list
+ = MALLOC(sizeof(FSUI_SearchList));
+ memset(list,
+ 0,
+ sizeof(FSUI_SearchList));
+ if ( (OK != read_int(fd, (int*) &list->state)) ||
+ (OK != read_int(fd, (int*) &list->anonymityLevel)) ||
+ (OK != read_int(fd, (int*) &list->sizeResultsReceived)) ||
+ (OK != read_int(fd, (int*) &list->sizeUnmatchedResultsReceived)) ||
+ (list->sizeResultsReceived > 1024*1024) ||
+ (list->sizeUnmatchedResultsReceived > 1024*1024) ) {
+ GE_BREAK(NULL, 0);
+ break;
+ }
+ fixState(&list->state);
+ buf = read_string(fd, 1024 * 1024);
+ if (buf == NULL) {
+ GE_BREAK(NULL, 0);
+ break;
+ }
+ list->uri
+ = ECRS_stringToUri(NULL, buf);
+ FREE(buf);
+ if (list->uri == NULL) {
+ GE_BREAK(NULL, 0);
+ break;
+ }
+ if (! ECRS_isKeywordUri(list->uri)) {
+ GE_BREAK(NULL, 0);
+ break;
+ }
+ list->numberOfURIKeys
+ = ECRS_countKeywordsOfUri(list->uri);
+ if (list->sizeResultsReceived > 0) {
+ list->resultsReceived
+ = MALLOC(list->sizeResultsReceived *
+ sizeof(ECRS_FileInfo));
+ memset(list->resultsReceived,
+ 0,
+ list->sizeResultsReceived *
+ sizeof(ECRS_FileInfo));
+ }
+ if (list->sizeUnmatchedResultsReceived > 0) {
+ list->unmatchedResultsReceived
+ = MALLOC(list->sizeUnmatchedResultsReceived *
+ sizeof(ResultPending));
+ memset(list->unmatchedResultsReceived,
+ 0,
+ list->sizeUnmatchedResultsReceived *
+ sizeof(ResultPending));
+ }
+ for (i=0;i<list->sizeResultsReceived;i++)
+ if (OK != readFileInfo(ctx->ectx,
+ fd,
+ &list->resultsReceived[i])) {
+ GE_BREAK(NULL, 0);
+ goto ERR;
+ }
+ for (i=0;i<list->sizeUnmatchedResultsReceived;i++) {
+ rp = &list->unmatchedResultsReceived[i];
+ if (OK != readFileInfo(ctx->ectx,
+ fd,
+ &rp->fi)) {
+ GE_BREAK(NULL, 0);
+ goto ERR;
+ }
+ if (OK != read_int(fd, (int*) &rp->matchingKeyCount)) {
+ GE_BREAK(NULL, 0);
+ goto ERR;
+ }
+ if ( (rp->matchingKeyCount > 1024) ||
+ (rp->matchingKeyCount >= list->numberOfURIKeys) ) {
+ GE_BREAK(NULL, 0);
+ goto ERR;
+ }
+ if (rp->matchingKeyCount > 0) {
+ rp->matchingKeys
+ = MALLOC(sizeof(HashCode512) *
+ rp->matchingKeyCount);
+ if (sizeof(HashCode512) *
+ rp->matchingKeyCount !=
+ READ(fd,
+ rp->matchingKeys,
+ sizeof(HashCode512) *
+ rp->matchingKeyCount)) {
+ GE_BREAK(NULL, 0);
+ goto ERR;
+ }
+ }
+ }
+ list->signalTerminate
+ = NO;
+ list->ctx
+ = ctx;
+
+ /* finally: prepend to list */
+ list->next
+ = ctx->activeSearches;
+ ctx->activeSearches
+ = list;
+ } /* end OUTER: 'while(1)' */
+ ERR:
+ /* error - deallocate 'list' */
+ for (i=0;i<list->sizeResultsReceived;i++) {
+ if (list->resultsReceived[i].uri != NULL)
+ ECRS_freeUri(list->resultsReceived[i].uri);
+ if (list->resultsReceived[i].meta != NULL)
+ ECRS_freeMetaData(list->resultsReceived[i].meta);
+ }
+ GROW(list->resultsReceived,
+ list->sizeResultsReceived,
+ 0);
+ for (i=0;i<list->sizeUnmatchedResultsReceived;i++) {
+ rp = &list->unmatchedResultsReceived[i];
+
+ if (rp->fi.uri != NULL)
+ ECRS_freeUri(rp->fi.uri);
+ if (rp->fi.meta != NULL)
+ ECRS_freeMetaData(rp->fi.meta);
+ FREENONNULL(rp->matchingKeys);
+ }
+ GROW(list->resultsReceived,
+ list->sizeResultsReceived,
+ 0);
+ if (list->uri != NULL)
+ ECRS_freeUri(list->uri);
+ FREE(list);
+ return SYSERR;
+}
+
+static int readDownloads(int fd,
+ struct FSUI_Context * ctx) {
+ memset(&ctx->activeDownloads,
+ 0,
+ sizeof(FSUI_DownloadList));
+ ctx->activeDownloads.child
+ = readDownloadList(ctx->ectx,
+ fd,
+ ctx,
+ &ctx->activeDownloads);
+ return OK;
+}
+
+static int readUploads(int fd,
+ struct FSUI_Context * ctx) {
+ int big;
+
+ while (1) {
+ READINT(big);
+ if (big != 1)
+ return OK;
+
+ /* FIXME: deserialize! */
+ }
+ return SYSERR;
+}
+
+static int readUnindex(int fd,
+ struct FSUI_Context * ctx) {
+ int big;
+
+ while (1) {
+ READINT(big);
+ if (big != 1)
+ return OK;
+
+ /* FIXME: deserialize! */
+ }
+ return SYSERR;
+}
+
+
+void FSUI_deserialize(struct FSUI_Context * ctx) {
+ int fd;
+
+ fd = -1;
+ if (0 != ACCESS(ctx->name, R_OK))
+ return;
+ fd = disk_file_open(ctx->ectx,
+ ctx->name,
+ O_RDONLY);
+ if (fd == -1)
+ return;
+
+ if ( (OK != checkMagic(fd)) ||
+ (OK != readCollection(fd, ctx) ) ||
+ (OK != readSearches(fd, ctx) ) ||
+ (OK != readDownloads(fd, ctx) ) ||
+ (OK != readUnindex(fd, ctx) ) ||
+ (OK != readUploads(fd, ctx) ) ) {
+ GE_BREAK(ctx->ectx, 0);
+ GE_LOG(ctx->ectx,
+ GE_WARNING | GE_BULK | GE_USER,
+ _("FSUI state file `%s' had syntax error at offset %u.\n"),
+ ctx->name,
+ lseek(fd, 0, SEEK_CUR));
+ }
+ CLOSE(fd);
+ UNLINK(ctx->name);
+}
Property changes on: GNUnet/src/applications/fs/fsui/deserialize.c
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: GNUnet/src/applications/fs/fsui/download.c
===================================================================
--- GNUnet/src/applications/fs/fsui/download.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/download.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -25,7 +25,7 @@
* @author Christian Grothoff
*
* TODO:
- * - does not signal all events properly!
+ * - can do better ETA computation (in case of suspend-resume)
*/
#include "platform.h"
@@ -63,7 +63,9 @@
if (isRoot == YES)
return OK; /* namespace ad, ignore */
- URITRACK_trackURI(ectx, parent->ctx->cfg, fi);
+ URITRACK_trackURI(ectx,
+ parent->ctx->cfg,
+ fi);
for (i=0;i<parent->completedDownloadsCount;i++)
if (ECRS_equalsUri(parent->completedDownloads[i],
fi->uri))
@@ -79,7 +81,8 @@
EXTRACTOR_FILENAME);
if (filename == NULL) {
char * tmp = ECRS_uriToString(fi->uri);
- GE_ASSERT(ectx, strlen(tmp) >= strlen(ECRS_URI_PREFIX) +
strlen(ECRS_FILE_INFIX));
+ GE_ASSERT(ectx,
+ strlen(tmp) >= strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX));
filename = STRDUP(&tmp[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)]);
FREE(tmp);
}
@@ -94,15 +97,18 @@
while (NULL != (dotdot = strstr(fullName, "..")))
dotdot[0] = dotdot[1] = '_';
disk_directory_create(ectx, fullName);
- strcat(fullName, DIR_SEPARATOR_STR);
+ strcat(fullName,
+ DIR_SEPARATOR_STR);
while (NULL != (dotdot = strstr(filename, "..")))
dotdot[0] = dotdot[1] = '_';
- strcat(fullName, filename);
+ strcat(fullName,
+ filename);
FREE(filename);
#if DEBUG_DTM
- GE_LOG(ectx, GE_DEBUG | GE_REQUEST | GE_USER,
- "Starting recursive download of `%s'\n",
- fullName);
+ GE_LOG(ectx,
+ GE_DEBUG | GE_REQUEST | GE_USER,
+ "Starting recursive download of `%s'\n",
+ fullName);
#endif
startDownload(parent->ctx,
parent->anonymityLevel,
@@ -128,19 +134,15 @@
FSUI_DownloadList * dl = cls;
FSUI_Event event;
struct ECRS_MetaData * md;
- FSUI_DownloadList * root;
- root = dl;
- while ( (root->parent != NULL) &&
- (root->parent != &dl->ctx->activeDownloads) )
- root = root->parent;
-
- dl->completedFile = completedBytes;
+ GE_ASSERT(dl->ctx->ectx,
+ dl->total == totalBytes);
+ dl->completed = completedBytes;
event.type = FSUI_download_progress;
- event.data.DownloadProgress.total = totalBytes;
- event.data.DownloadProgress.completed = dl->completed + completedBytes;
+ event.data.DownloadProgress.total = dl->total;
+ event.data.DownloadProgress.completed = dl->completed;
event.data.DownloadProgress.last_offset = lastBlockOffset;
- event.data.DownloadProgress.eta = eta;
+ event.data.DownloadProgress.eta = eta; /* FIXME: we can do better in FSUI! */
event.data.DownloadProgress.last_block = lastBlock;
event.data.DownloadProgress.last_size = lastBlockSize;
event.data.DownloadProgress.filename = dl->filename;
@@ -148,7 +150,7 @@
event.data.DownloadProgress.dc.pos = dl;
event.data.DownloadProgress.dc.cctx = dl->cctx;
event.data.DownloadProgress.dc.ppos = dl->parent;
- event.data.DownloadProgress.dc.pcctx = dl->parent != NULL ? dl->parent->cctx
: NULL;
+ event.data.DownloadProgress.dc.pcctx = dl->parent->cctx;
dl->ctx->ecb(dl->ctx->ecbClosure,
&event);
if ( (lastBlockOffset == 0) &&
@@ -185,11 +187,9 @@
testTerminate(void * cls) {
FSUI_DownloadList * dl = cls;
- if (dl->state != FSUI_DOWNLOAD_ACTIVE) {
+ if (dl->state != FSUI_ACTIVE)
return SYSERR;
- } else {
- return OK;
- }
+ return OK;
}
/**
@@ -199,11 +199,9 @@
FSUI_DownloadList * dl = cls;
int ret;
FSUI_Event event;
- struct ECRS_MetaData * md;
- FSUI_DownloadList * root;
- unsigned long long totalBytes;
struct GE_Context * ectx;
+ dl->startTime = get_time() - dl->runTime;
ectx = dl->ctx->ectx;
#if DEBUG_DTM
GE_LOG(ectx,
@@ -223,29 +221,29 @@
&testTerminate,
dl);
if (ret == OK) {
- dl->state = FSUI_DOWNLOAD_COMPLETED;
- totalBytes = ECRS_fileSize(dl->uri);
- } else {
-#if DEBUG_DTM
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Download thread for `%s' failed (aborted or error)!\n",
- dl->filename);
-#endif
- if (dl->state == FSUI_DOWNLOAD_ACTIVE)
- dl->state = FSUI_DOWNLOAD_ERROR;
- else if ( (dl->state != FSUI_DOWNLOAD_ABORTED) &&
- (dl->state != FSUI_DOWNLOAD_SUSPENDING) )
- GE_BREAK(ectx, 0);
- totalBytes = 0;
+ dl->state = FSUI_COMPLETED;
+ event.type = FSUI_download_complete;
+ event.data.DownloadCompleted.total = dl->total;
+ event.data.DownloadCompleted.filename = dl->filename;
+ event.data.DownloadCompleted.uri = dl->uri;
+ event.data.DownloadCompleted.dc.pos = dl;
+ event.data.DownloadCompleted.dc.cctx = dl->cctx;
+ event.data.DownloadCompleted.dc.ppos = dl->parent;
+ event.data.DownloadCompleted.dc.pcctx = dl->parent->cctx;
+ dl->ctx->ecb(dl->ctx->ecbClosure,
+ &event);
+ } else if (dl->state == FSUI_ACTIVE) {
+ /* ECRS error, we did not signal to abort */
+ dl->state = FSUI_ERROR;
+ event.type = FSUI_download_error;
+ event.data.DownloadError.message = _("ECRS download failed (see logs)");
+ event.data.DownloadError.dc.pos = dl;
+ event.data.DownloadError.dc.cctx = dl->cctx;
+ event.data.DownloadError.dc.ppos = dl->parent;
+ event.data.DownloadError.dc.pcctx = dl->parent->cctx;
+ dl->ctx->ecb(dl->ctx->ecbClosure,
+ &event);
}
- root = dl;
- while (root->parent != &dl->ctx->activeDownloads) {
- root->completed += totalBytes;
- root = root->parent;
- }
- root->completed += totalBytes;
-
if ( (ret == OK) &&
(dl->is_recursive) &&
@@ -253,7 +251,10 @@
char * dirBlock;
int fd;
char * fn;
+ size_t totalBytes;
+ struct ECRS_MetaData * md;
+ totalBytes = ECRS_fileSize(dl->uri);
fn = MALLOC(strlen(dl->filename) + 3 + strlen(GNUNET_DIRECTORY_EXT));
strcpy(fn, dl->filename);
if (fn[strlen(fn)-1] == '/') {
@@ -298,51 +299,6 @@
}
FREE(fn);
}
- if (ret != OK) {
- switch (dl->state) {
- case FSUI_DOWNLOAD_ABORTED:
- event.type = FSUI_download_aborted;
- event.data.DownloadError.message = _("Download aborted.");
- break;
- case FSUI_DOWNLOAD_ERROR:
- event.type = FSUI_download_error;
- event.data.DownloadError.message = _("ECRS download failed (see logs).");
- break;
- case FSUI_DOWNLOAD_SUSPENDING:
- event.type = FSUI_download_suspending;
- event.data.DownloadError.message = _("ECRS download suspending.");
- break;
- default:
- event.type = FSUI_download_error;
- event.data.DownloadError.message = _("Unexpected download state.");
- printf("State: %u\n", dl->state);
- GE_BREAK(ectx, 0);
- }
- event.data.DownloadError.dc.pos = dl;
- event.data.DownloadError.dc.cctx = dl->cctx;
- event.data.DownloadError.dc.ppos = dl->parent;
- event.data.DownloadError.dc.pcctx = dl->parent != NULL ? dl->parent->cctx
: NULL;
- dl->ctx->ecb(dl->ctx->ecbClosure,
- &event);
- } else {
- GE_ASSERT(ectx, dl != &dl->ctx->activeDownloads);
- while ( (dl != NULL) &&
- (dl->ctx != NULL) &&
- (dl != &dl->ctx->activeDownloads) ) {
- event.type = FSUI_download_complete;
- event.data.DownloadComplete.total = dl->total;
- event.data.DownloadComplete.filename = dl->filename;
- event.data.DownloadComplete.uri = dl->uri;
- event.data.DownloadComplete.dc.pos = dl;
- event.data.DownloadComplete.dc.cctx = dl->cctx;
- event.data.DownloadComplete.dc.ppos = dl->parent;
- event.data.DownloadComplete.dc.pcctx = dl->parent != NULL ?
dl->parent->cctx : NULL;
- dl->ctx->ecb(dl->ctx->ecbClosure,
- &event);
- dl = dl->parent;
- }
- }
- dl = cls;
#if DEBUG_DTM
GE_LOG(ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
@@ -350,6 +306,7 @@
dl->filename,
ret == OK ? "COMPLETED" : "ABORTED");
#endif
+ dl->runTime = get_time() - dl->startTime;
return NULL;
}
@@ -364,8 +321,7 @@
const char * filename,
FSUI_DownloadList * parent) {
FSUI_DownloadList * dl;
- FSUI_DownloadList * root;
- unsigned long long totalBytes;
+ FSUI_Event event;
GE_ASSERT(NULL, ctx != NULL);
GE_ASSERT(NULL, parent != NULL);
@@ -375,9 +331,12 @@
return NULL;
}
dl = MALLOC(sizeof(FSUI_DownloadList));
- memset(dl, 0, sizeof(FSUI_DownloadList));
- dl->startTime = get_time();
- dl->state = FSUI_DOWNLOAD_PENDING;
+ memset(dl,
+ 0,
+ sizeof(FSUI_DownloadList));
+ dl->startTime = 0; /* not run at all so far! */
+ dl->runTime = 0; /* not run at all so far! */
+ dl->state = FSUI_PENDING;
dl->is_recursive = is_recursive;
dl->parent = parent;
dl->is_directory = SYSERR; /* don't know */
@@ -389,14 +348,20 @@
dl->child = NULL;
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;
- }
+ /* signal start! */
+ event.type = FSUI_download_error;
+ event.data.DownloadStarted.filename = dl->filename;
+ event.data.DownloadStarted.total = ECRS_fileSize(uri);
+ event.data.DownloadStarted.uri = uri;
+ event.data.DownloadStarted.anonymityLevel = anonymityLevel;
+ event.data.DownloadStarted.dc.pos = dl;
+ event.data.DownloadStarted.dc.cctx = dl->cctx;
+ event.data.DownloadStarted.dc.ppos = dl->parent;
+ event.data.DownloadStarted.dc.pcctx = dl->parent->cctx;
+ dl->cctx = ctx->ecb(ctx->ecbClosure,
+ &event);
+
return dl;
}
@@ -429,11 +394,11 @@
/**
* Starts or stops download threads in accordance with thread pool
* size and active downloads. Call only while holding FSUI lock (or
- * during start/stop).
+ * during start/stop). Called from cron job in fsui.c.
*
* @return YES if change done that may require re-trying
*/
-int updateDownloadThread(FSUI_DownloadList * list) {
+int FSUI_updateDownloadThread(FSUI_DownloadList * list) {
struct GE_Context * ectx;
FSUI_DownloadList * dpos;
void * unused;
@@ -455,7 +420,7 @@
/* should this one be started? */
if ( (list->ctx->threadPoolSize
> list->ctx->activeDownloadThreads) &&
- (list->state == FSUI_DOWNLOAD_PENDING) &&
+ (list->state == FSUI_PENDING) &&
( (list->total > list->completed) ||
(list->total == 0) ) ) {
#if DEBUG_DTM
@@ -464,7 +429,7 @@
"Download thread manager starts download of file `%s'\n",
list->filename);
#endif
- list->state = FSUI_DOWNLOAD_ACTIVE;
+ list->state = FSUI_ACTIVE;
list->handle = PTHREAD_CREATE(&downloadThread,
list,
32 * 1024);
@@ -474,14 +439,14 @@
GE_LOG_STRERROR(ectx,
GE_ADMIN | GE_USER | GE_BULK | GE_ERROR,
"pthread_create");
- list->state = FSUI_DOWNLOAD_ERROR_JOINED;
+ list->state = FSUI_ERROR_JOINED;
}
}
/* should this one be stopped? */
if ( (list->ctx->threadPoolSize
< list->ctx->activeDownloadThreads) &&
- (list->state == FSUI_DOWNLOAD_ACTIVE) ) {
+ (list->state == FSUI_ACTIVE) ) {
#if DEBUG_DTM
GE_LOG(ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
@@ -490,20 +455,20 @@
list->ctx->activeDownloadThreads,
list->ctx->threadPoolSize);
#endif
- list->state = FSUI_DOWNLOAD_SUSPENDING;
+ list->state = FSUI_SUSPENDING;
GE_ASSERT(ectx, list->handle != NULL);
PTHREAD_STOP_SLEEP(list->handle);
PTHREAD_JOIN(list->handle,
&unused);
list->ctx->activeDownloadThreads--;
- list->state = FSUI_DOWNLOAD_PENDING;
+ list->state = FSUI_PENDING;
ret = YES;
}
/* has this one "died naturally"? */
- if ( (list->state == FSUI_DOWNLOAD_COMPLETED) ||
- (list->state == FSUI_DOWNLOAD_ABORTED) ||
- (list->state == FSUI_DOWNLOAD_ERROR) ) {
+ if ( (list->state == FSUI_COMPLETED) ||
+ (list->state == FSUI_ABORTED) ||
+ (list->state == FSUI_ERROR) ) {
#if DEBUG_DTM
GE_LOG(ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
@@ -519,7 +484,7 @@
dpos = list->child;
while (dpos != NULL) {
- if (YES == updateDownloadThread(dpos))
+ if (YES == FSUI_updateDownloadThread(dpos))
ret = YES;
dpos = dpos->next;
}
@@ -528,66 +493,54 @@
/**
- * 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!).
+ * Abort a download (and all child-downloads).
+ *
+ * @return SYSERR if no such download is pending,
+ * NO if the download has already finished
*/
-void freeDownloadList(FSUI_DownloadList * list) {
- FSUI_DownloadList * dpos;
- int i;
+int FSUI_abortDownload(struct FSUI_Context * ctx,
+ struct FSUI_DownloadList * dl) {
+ FSUI_Event event;
+ struct FSUI_DownloadList * c;
- GE_ASSERT(NULL, list->state != FSUI_DOWNLOAD_ACTIVE);
-
- /* first, find our predecessor and
- unlink us from the tree! */
- dpos = list->parent;
- GE_ASSERT(NULL, dpos != NULL);
- if (dpos->child == list) {
- dpos->child = list->next;
- } else {
- dpos = dpos->child;
- while ( (dpos != NULL) &&
- (dpos->next != list) )
- dpos = dpos->next;
- GE_ASSERT(NULL, 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);
+ GE_ASSERT(ctx->ectx, dl != NULL);
+ c = dl->child;
+ while (c != NULL) {
+ FSUI_abortDownload(ctx, c);
+ c = c->next;
+ }
+ if ( (dl->state != FSUI_ACTIVE) &&
+ (dl->state != FSUI_PENDING) )
+ return NO;
+ dl->state = FSUI_ABORTED;
+ PTHREAD_STOP_SLEEP(dl->handle);
+ event.type = FSUI_download_aborted;
+ event.data.DownloadAborted.dc.pos = dl;
+ event.data.DownloadAborted.dc.cctx = dl->cctx;
+ event.data.DownloadAborted.dc.ppos = dl->parent;
+ event.data.DownloadAborted.dc.pcctx = dl->parent->cctx;
+ ctx->ecb(ctx->ecbClosure,
+ &event);
+ return OK;
}
/**
- * Abort a download.
+ * Stops a download (and all downloads that are
+ * child downloads of this download).
*
* @return SYSERR if no such download is pending
*/
int FSUI_stopDownload(struct FSUI_Context * ctx,
struct FSUI_DownloadList * dl) {
- FSUI_DownloadList * prev;
- struct GE_Context * ectx;
- unsigned int backup;
+ void * unused;
+ struct FSUI_DownloadList * prev;
+ FSUI_Event event;
+ int i;
- ectx = ctx->ectx;
- if (dl == NULL) {
- GE_BREAK(ectx, 0);
- return SYSERR;
- }
-#if 0
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "FSUI_stopDownload called.\n");
-#endif
+ GE_ASSERT(ctx->ectx, dl != NULL);
+ while (dl->child != NULL)
+ FSUI_stopDownload(ctx,
+ dl->child);
MUTEX_LOCK(ctx->lock);
prev = (dl->parent != NULL) ? dl->parent->child : ctx->activeDownloads.child;
while ( (prev != dl) &&
@@ -596,17 +549,38 @@
prev = prev->next;
if (prev == NULL) {
MUTEX_UNLOCK(ctx->lock);
- GE_LOG(ectx,
+ GE_LOG(ctx->ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
"FSUI_stopDownload failed to locate download.\n");
return SYSERR;
}
- backup = ctx->threadPoolSize;
- ctx->threadPoolSize = 0;
- updateDownloadThread(dl);
- freeDownloadList(dl);
- ctx->threadPoolSize = backup;
+ if (prev == dl)
+ dl->parent->child = dl->next; /* first child of parent */
+ else
+ prev->next = dl->next; /* not first child */
MUTEX_UNLOCK(ctx->lock);
+ if ( (dl->state == FSUI_COMPLETED) ||
+ (dl->state == FSUI_ABORTED) ||
+ (dl->state == FSUI_ERROR) ) {
+ PTHREAD_JOIN(dl->handle,
+ &unused);
+ dl->state++; /* add _JOINED */
+ }
+ event.type = FSUI_download_stopped;
+ event.data.DownloadStopped.dc.pos = dl;
+ event.data.DownloadStopped.dc.cctx = dl->cctx;
+ event.data.DownloadStopped.dc.ppos = dl->parent;
+ event.data.DownloadStopped.dc.pcctx = dl->parent->cctx;
+ ctx->ecb(ctx->ecbClosure,
+ &event);
+ for (i=dl->completedDownloadsCount-1;i>=0;i--)
+ ECRS_freeUri(dl->completedDownloads[i]);
+ GROW(dl->completedDownloads,
+ dl->completedDownloadsCount,
+ 0);
+ ECRS_freeUri(dl->uri);
+ FREE(dl->filename);
+ FREE(dl);
return OK;
}
Modified: GNUnet/src/applications/fs/fsui/fsui.c
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/fsui.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -24,9 +24,11 @@
* @author Christian Grothoff
*
* TODO:
- * - upload serialize/deserialize/resume
- * - unindex deserialize/resume
- * - events for suspend (!)
+ * - upload tree representation (currently flat list!)
+ * - download tree free memory
+ * - resume signaling
+ * - actual resuming (start threads)
+ * - better ETA calculation for download resume
*/
#include "platform.h"
@@ -36,362 +38,13 @@
#define DEBUG_PERSISTENCE NO
+/* ***************** CRON code ***************** */
+
#define FSUI_UDT_FREQUENCY (2 * cronSECONDS)
-#define READINT(a) \
- if (sizeof(int) != READ(fd, &big, sizeof(int))) \
- goto ERR; \
- else \
- a = ntohl(big)
-#define READLONG(a) \
- if (sizeof(long long) != READ(fd, &bigl, sizeof(long long))) \
- goto ERR; \
- else \
- a = ntohll(bigl)
-
-static struct ECRS_URI * readURI(struct GE_Context * ectx,
- int fd) {
- char * buf;
- unsigned int big;
- struct ECRS_URI * ret;
- unsigned int size;
-
- READINT(size);
- buf = MALLOC(size+1);
- buf[size] = '\0';
- if (size != READ(fd,
- buf,
- size)) {
- FREE(buf);
- return NULL;
- }
- ret = ECRS_stringToUri(ectx, buf);
- FREE(buf);
- return ret;
- ERR:
- return NULL;
-}
-
-static void doResumeEvents(struct FSUI_DownloadList * ret,
- FSUI_Context * ctx) {
- FSUI_Event event;
-
- while (ret != NULL) {
- event.type = FSUI_download_resuming;
- event.data.DownloadResuming.dc.pos = ret;
- event.data.DownloadResuming.dc.cctx = ret->cctx;
- event.data.DownloadResuming.dc.ppos = ret->parent;
- event.data.DownloadResuming.dc.pcctx = ret->parent != NULL ?
ret->parent->cctx : NULL;
- event.data.DownloadResuming.eta = get_time(); /* best guess */
- event.data.DownloadResuming.total = ret->total;
- event.data.DownloadResuming.completed = ret->completedFile;
- event.data.DownloadResuming.anonymityLevel = ret->anonymityLevel;
- event.data.DownloadResuming.uri = ret->uri;
- ret->cctx = ctx->ecb(ctx->ecbClosure, &event);
- if (ret->child != NULL)
- doResumeEvents(ret->child,
- ctx);
- ret = ret->next;
- }
-}
-
/**
- * (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)
+ * Cron job for download load management.
*/
-static FSUI_DownloadList * readDownloadList(struct GE_Context * ectx,
- int fd,
- FSUI_Context * ctx,
- FSUI_DownloadList * parent) {
- char zaro;
- FSUI_DownloadList * ret;
- unsigned int big;
- unsigned long long bigl;
- int i;
- int ok;
-
- GE_ASSERT(ectx, ctx != NULL);
- if (1 != READ(fd, &zaro, sizeof(char))) {
- GE_BREAK(ectx, 0);
- return NULL;
- }
- if (zaro == '\0')
- return NULL;
- ret = MALLOC(sizeof(FSUI_DownloadList));
- memset(ret,
- 0,
- sizeof(FSUI_DownloadList));
- ret->ctx = ctx;
- READINT(ret->is_recursive);
- READINT(ret->is_directory);
- READINT(ret->anonymityLevel);
- READINT(ret->completedDownloadsCount);
- READINT(ret->state);
- switch (ret->state) { /* try to correct errors */
- case FSUI_DOWNLOAD_ACTIVE:
- ret->state = FSUI_DOWNLOAD_PENDING;
- break;
- case FSUI_DOWNLOAD_PENDING:
- case FSUI_DOWNLOAD_COMPLETED_JOINED:
- case FSUI_DOWNLOAD_ABORTED_JOINED:
- case FSUI_DOWNLOAD_ERROR_JOINED:
- break;
- case FSUI_DOWNLOAD_ERROR:
- ret->state = FSUI_DOWNLOAD_ERROR_JOINED;
- break;
- case FSUI_DOWNLOAD_ABORTED:
- ret->state = FSUI_DOWNLOAD_ABORTED_JOINED;
- break;
- case FSUI_DOWNLOAD_COMPLETED:
- ret->state = FSUI_DOWNLOAD_COMPLETED_JOINED;
- break;
- default:
- ret->state = FSUI_DOWNLOAD_PENDING;
- break;
- }
- READINT(big);
- if (big > 1024 * 1024) {
- GE_BREAK(ectx, 0);
- goto ERR;
- }
- ret->filename = MALLOC(big+1);
- if (big != READ(fd, ret->filename, big)) {
- GE_BREAK(ectx, 0);
- goto ERR;
- }
- ret->filename[big] = '\0';
- READLONG(ret->total);
- READLONG(ret->completed);
- ret->completedFile = 0;
- READLONG(ret->startTime);
- ret->startTime = get_time() - ret->startTime;
- ret->uri
- = readURI(ectx, fd);
- if (ret->completedDownloadsCount > 0)
- ret->completedDownloads
- = MALLOC(sizeof(struct ECRS_URI *) *
- ret->completedDownloadsCount);
- else
- ret->completedDownloads
- = NULL;
- ok = ret->uri != NULL;
- for (i=0;i<ret->completedDownloadsCount;i++) {
- ret->completedDownloads[i]
- = readURI(ectx, fd);
- if (ret->completedDownloads[i] == NULL)
- ok = NO;
- }
- if (NO == ok) {
- GE_BREAK(ectx, 0);
- goto ERR;
- }
- ret->parent = parent;
- ret->next = readDownloadList(ectx,
- fd,
- ctx,
- parent);
- ret->child = readDownloadList(ectx,
- fd,
- ctx,
- ret);
-#if DEBUG_PERSISTENCE
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "FSUI persistence: restoring download `%s': (%llu, %llu)\n",
- ret->filename,
- ret->completed,
- ret->total);
-#endif
- return ret;
- ERR:
- FREENONNULL(ret->filename);
- if (ret->uri != NULL)
- ECRS_freeUri(ret->uri);
- for (i=0;i<ret->completedDownloadsCount;i++) {
- if (ret->completedDownloads[i] != NULL)
- ECRS_freeUri(ret->completedDownloads[i]);
- }
- FREE(ret);
- GE_LOG(ectx,
- GE_WARNING | GE_BULK | GE_USER,
- _("FSUI persistence: error restoring download\n"));
- return NULL;
-}
-
-static void WRITEINT(int fd,
- int val) {
- int big;
- big = htonl(val);
- WRITE(fd, &big, sizeof(int));
-}
-
-static void WRITELONG(int fd,
- long long val) {
- long long big;
- big = htonll(val);
- WRITE(fd, &big, sizeof(long long));
-}
-
-static void writeURI(int fd,
- const struct ECRS_URI * uri) {
- char * buf;
- unsigned int size;
-
- buf = ECRS_uriToString(uri);
- size = strlen(buf);
- WRITEINT(fd, size);
- WRITE(fd,
- buf,
- size);
- FREE(buf);
-}
-
-static void WRITESTRING(int fd,
- const char * name) {
- WRITEINT(fd,
- strlen(name));
- WRITE(fd,
- name,
- strlen(name));
-}
-
-/**
- * (recursively) write a download list.
- */
-static void writeDownloadList(struct GE_Context * ectx,
- int fd,
- FSUI_Context * ctx,
- FSUI_DownloadList * list) {
- static char zero = '\0';
- static char nonzero = '+';
- int i;
- FSUI_Event event;
-
- if (list == NULL) {
- WRITE(fd, &zero, sizeof(char));
- return;
- }
-#if DEBUG_PERSISTENCE
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Serializing download state of download `%s': (%llu, %llu)\n",
- list->filename,
- list->completed,
- list->total);
-#endif
- WRITE(fd, &nonzero, sizeof(char));
-
- WRITEINT(fd, list->is_recursive);
- WRITEINT(fd, list->is_directory);
- WRITEINT(fd, list->anonymityLevel);
- WRITEINT(fd, list->completedDownloadsCount);
- WRITEINT(fd, list->state);
- WRITEINT(fd, strlen(list->filename));
- WRITE(fd,
- list->filename,
- strlen(list->filename));
- WRITELONG(fd, list->total);
- WRITELONG(fd, list->completed);
- WRITELONG(fd, get_time() - list->startTime);
- writeURI(fd, list->uri);
- for (i=0;i<list->completedDownloadsCount;i++)
- writeURI(fd, list->completedDownloads[i]);
- writeDownloadList(ectx,
- fd,
- ctx,
- list->next);
- writeDownloadList(ectx,
- fd,
- ctx,
- list->child);
- event.type = FSUI_download_suspending;
- event.data.DownloadSuspending.dc.pos = list;
- event.data.DownloadSuspending.dc.cctx = list->cctx;
- event.data.DownloadSuspending.dc.ppos = list->parent;
- event.data.DownloadSuspending.dc.pcctx = list->parent != NULL ?
list->parent->cctx : NULL;
- ctx->ecb(ctx->ecbClosure, &event);
-}
-
-/**
- * Read file info from file.
- *
- * @return OK on success, SYSERR on error
- */
-static int readFileInfo(struct GE_Context * ectx,
- int fd,
- ECRS_FileInfo * fi) {
- unsigned int size;
- unsigned int big;
- char * buf;
-
- fi->meta = NULL;
- fi->uri = NULL;
- READINT(size);
- if (size > 1024 * 1024) {
- GE_BREAK(ectx, 0);
- return SYSERR;
- }
- buf = MALLOC(size);
- if (size != READ(fd,
- buf,
- size)) {
- FREE(buf);
- GE_BREAK(ectx, 0);
- return SYSERR;
- }
- fi->meta = ECRS_deserializeMetaData(ectx,
- buf,
- size);
- if (fi->meta == NULL) {
- FREE(buf);
- GE_BREAK(ectx, 0);
- return SYSERR;
- }
- FREE(buf);
-
- fi->uri
- = readURI(ectx, fd);
- if (fi->uri == NULL) {
- ECRS_freeMetaData(fi->meta);
- fi->meta = NULL;
- GE_BREAK(ectx, 0);
- return SYSERR;
- }
- return OK;
- ERR:
- GE_BREAK(ectx, 0);
- return SYSERR;
-}
-
-static void writeFileInfo(struct GE_Context * ectx,
- int fd,
- const ECRS_FileInfo * fi) {
- unsigned int size;
- char * buf;
-
- size = ECRS_sizeofMetaData(fi->meta,
- ECRS_SERIALIZE_FULL | ECRS_SERIALIZE_NO_COMPRESS);
- if (size > 1024 * 1024)
- size = 1024 * 1024;
- buf = MALLOC(size);
- ECRS_serializeMetaData(ectx,
- fi->meta,
- buf,
- size,
- ECRS_SERIALIZE_PART | ECRS_SERIALIZE_NO_COMPRESS);
- WRITEINT(fd, size);
- WRITE(fd,
- buf,
- size);
- FREE(buf);
- writeURI(fd, fi->uri);
-}
-
static void updateDownloadThreads(void * c) {
FSUI_Context * ctx = c;
FSUI_DownloadList * dpos;
@@ -405,12 +58,37 @@
"Download thread manager schedules pending downloads...\n");
#endif
while (dpos != NULL) {
- updateDownloadThread(dpos);
+ FSUI_updateDownloadThread(dpos);
dpos = dpos->next;
}
MUTEX_UNLOCK(ctx->lock);
}
+/* ******************* START code *********************** */
+
+static void signalDownloadResume(struct FSUI_DownloadList * ret,
+ FSUI_Context * ctx) {
+ FSUI_Event event;
+
+ while (ret != NULL) {
+ event.type = FSUI_download_resumed;
+ event.data.DownloadResumed.dc.pos = ret;
+ event.data.DownloadResumed.dc.cctx = ret->cctx;
+ event.data.DownloadResumed.dc.ppos = ret->parent;
+ event.data.DownloadResumed.dc.pcctx = ret->parent->cctx;
+ event.data.DownloadResumed.eta = get_time(); /* FIXME: can do better here!
*/
+ event.data.DownloadResumed.total = ret->total;
+ event.data.DownloadResumed.completed = ret->completed;
+ event.data.DownloadResumed.anonymityLevel = ret->anonymityLevel;
+ event.data.DownloadResumed.uri = ret->uri;
+ ret->cctx = ctx->ecb(ctx->ecbClosure, &event);
+ if (ret->child != NULL)
+ signalDownloadResume(ret->child,
+ ctx);
+ ret = ret->next;
+ }
+}
+
/**
* Start FSUI manager. Use the given progress callback to notify the
* UI about events. Start processing pending activities that were
@@ -429,21 +107,18 @@
FSUI_Event event;
FSUI_Context * ret;
FSUI_SearchList * list;
- ResultPending * rp;
char * fn;
char * gh;
- int fd;
- int i;
GE_ASSERT(ectx, cfg != NULL);
ret = MALLOC(sizeof(FSUI_Context));
- memset(ret, 0, sizeof(FSUI_Context));
+ memset(ret,
+ 0,
+ sizeof(FSUI_Context));
ret->activeDownloads.state
- = FSUI_DOWNLOAD_PENDING; /* !? */
- ret->activeDownloads.ctx
- = ret;
- ret->cfg
- = cfg;
+ = FSUI_PENDING; /* !? */
+ ret->activeDownloads.ctx = ret;
+ ret->cfg = cfg;
ret->ecb = cb;
ret->ecbClosure = closure;
ret->threadPoolSize = threadPoolSize;
@@ -462,6 +137,8 @@
strcat(fn, DIR_SEPARATOR_STR);
strcat(fn, name);
ret->name = fn;
+
+ /* 1) read state in */
if (doResume) {
ret->ipc = IPC_SEMAPHORE_CREATE(ectx,
fn,
@@ -478,310 +155,108 @@
GE_INFO | GE_REQUEST | GE_USER,
"Aquired IPC lock.\n");
#endif
- fd = -1;
strcat(fn, ".res");
- if (0 == ACCESS(fn, R_OK))
- fd = disk_file_open(ectx,
- fn,
- O_RDONLY);
- if (fd != -1) {
- char magic[8];
- unsigned int big;
+ FSUI_deserialize(ret);
+ } else {
+ ret->ipc = NULL;
+ }
+ ret->lock = MUTEX_CREATE(YES);
- /* ****** check magic ******* */
- if (8 != READ(fd, magic, 8)) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (0 != memcmp(magic,
- "FSUI00\n\0",
- 8)) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- /* ******* deserialize state **** */
+ /* 2) do resume events */
+ /* 2a) signal download restarts */
+ signalDownloadResume(ret->activeDownloads.child,
+ ret);
+ /* 2b) signal search restarts */
- /* deserialize collection data */
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (ntohl(big) > 16 * 1024 * 1024) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (big == 0) {
- ret->collectionData = NULL;
- } else {
- ret->collectionData
- = MALLOC(ntohl(big));
- if (ntohl(big) - sizeof(unsigned int) !=
- READ(fd,
- &ret->collectionData[1],
- ntohl(big) - sizeof(unsigned int))) {
- FREE(ret->collectionData);
- ret->collectionData = NULL;
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- }
+ event.type = FSUI_search_resumed;
+ event.data.SearchResumed.sc.pos = list;
+ event.data.SearchResumed.sc.cctx = NULL;
+ event.data.SearchResumed.fis = list->resultsReceived;
+ event.data.SearchResumed.fisSize = list->sizeResultsReceived;
+ event.data.SearchResumed.anonymityLevel = list->anonymityLevel;
+ event.data.SearchResumed.searchURI = list->uri;
+ list->cctx = cb(closure, &event);
- /* deserialize pending searches! */
- while (1) {
- char * buf;
+ /* 2c) signal upload restarts */
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (ntohl(big) == 0)
- break;
- if (ntohl(big) > 1024 * 1024) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- buf
- = MALLOC(ntohl(big)+1);
- buf[ntohl(big)] = '\0';
- if (ntohl(big) !=
- READ(fd,
- buf,
- ntohl(big))) {
- FREE(buf);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- list
- = MALLOC(sizeof(FSUI_SearchList));
- list->uri
- = ECRS_stringToUri(ectx, buf);
- FREE(buf);
- if (list->uri == NULL) {
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (! ECRS_isKeywordUri(list->uri)) {
- ECRS_freeUri(list->uri);
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- list->numberOfURIKeys
- = ECRS_countKeywordsOfUri(list->uri);
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- ECRS_freeUri(list->uri);
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- list->anonymityLevel
- = ntohl(big);
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- ECRS_freeUri(list->uri);
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- list->sizeResultsReceived
- = ntohl(big);
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- ECRS_freeUri(list->uri);
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- list->sizeUnmatchedResultsReceived
- = ntohl(big);
- if ( (list->sizeResultsReceived > 1024*1024) ||
- (list->sizeUnmatchedResultsReceived > 1024*1024) ) {
- ECRS_freeUri(list->uri);
- FREE(list);
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (list->sizeResultsReceived > 0)
- list->resultsReceived
- = MALLOC(list->sizeResultsReceived *
- sizeof(ECRS_FileInfo));
- else
- list->resultsReceived
- = NULL;
- if (list->sizeUnmatchedResultsReceived > 0)
- list->unmatchedResultsReceived
- = MALLOC(list->sizeUnmatchedResultsReceived *
- sizeof(ResultPending));
- else
- list->unmatchedResultsReceived
- = NULL;
- for (i=0;i<list->sizeResultsReceived;i++)
- readFileInfo(ectx,
- fd,
- &list->resultsReceived[i]);
- for (i=0;i<list->sizeUnmatchedResultsReceived;i++) {
- rp = &list->unmatchedResultsReceived[i];
- readFileInfo(ectx,
- fd,
- &rp->fi);
-
- if (sizeof(unsigned int) !=
- READ(fd,
- &big,
- sizeof(unsigned int))) {
- GE_BREAK(ectx, 0);
- goto WARNL;
- }
- rp->matchingKeyCount
- = ntohl(big);
- if ( (rp->matchingKeyCount > 1024) ||
- (rp->matchingKeyCount >
- list->numberOfURIKeys) ) {
- GE_BREAK(ectx, 0);
- goto WARNL;
- }
-
- if (rp->matchingKeyCount > 0)
- rp->matchingKeys
- = MALLOC(sizeof(HashCode512) *
- rp->matchingKeyCount);
- else
- rp->matchingKeys
- = NULL;
- if (sizeof(HashCode512) *
- rp->matchingKeyCount !=
- READ(fd,
- rp->matchingKeys,
- sizeof(HashCode512) *
- rp->matchingKeyCount)) {
- GE_BREAK(ectx, 0);
- goto WARNL;
- }
- }
-
-
- list->signalTerminate
- = NO;
- list->ctx
- = ret;
- /* start search thread! */
+ /* 2d) signal unindex restarts */
+
+ /* 3) restart processing */
+ ret->cron = cron_create(ectx);
+ /* 3a) resume downloads */
+ cron_add_job(ret->cron,
+ &updateDownloadThreads,
+ 0,
+ FSUI_UDT_FREQUENCY,
+ ret);
+ cron_start(ret->cron);
+ /* 3b) resume uploads */
+
+ /* 3c) resume unindexing */
+
+ /* 3d) resume searching */
+
#if DEBUG_PERSISTENCE
GE_LOG(ectx,
GE_DEBUG | GE_REQUEST | GE_USER,
"FSUI persistence: restarting search\n");
#endif
- list->handle = PTHREAD_CREATE(&searchThread,
+ list->handle = PTHREAD_CREATE(&FSUI_searchThread,
list,
32 * 1024);
if (list->handle == NULL)
GE_DIE_STRERROR(ectx,
GE_FATAL | GE_ADMIN | GE_IMMEDIATE,
"pthread_create");
-
- /* finally: prepend to list */
- list->next
- = ret->activeSearches;
- ret->activeSearches
- = list;
- /* then: signal event handler! */
- event.type = FSUI_search_resuming;
- event.data.SearchResuming.sc.pos = list;
- event.data.SearchResuming.sc.cctx = NULL;
- event.data.SearchResuming.fis = list->resultsReceived;
- event.data.SearchResuming.fisSize = list->sizeResultsReceived;
- event.data.SearchResuming.anonymityLevel = list->anonymityLevel;
- event.data.SearchResuming.searchURI = list->uri;
- list->cctx = cb(closure, &event);
- }
- memset(&ret->activeDownloads,
- 0,
- sizeof(FSUI_DownloadList));
- ret->activeDownloads.child
- = readDownloadList(ectx,
- fd,
- ret,
- &ret->activeDownloads);
- doResumeEvents(ret->activeDownloads.child,
- ret);
- /* deserialize uploads */
- while (1) {
- if (sizeof(unsigned int) !=
- READ(fd, &big, sizeof(unsigned int))) {
- GE_BREAK(ectx, 0);
- goto WARN;
- }
- if (ntohl(big) != 1)
- break; /* no more uploads */
-
- }
+ return ret;
+}
- /* success, read complete! */
- goto END;
- WARNL:
- for (i=0;i<list->sizeResultsReceived;i++) {
- if (list->resultsReceived[i].uri != NULL)
- ECRS_freeUri(list->resultsReceived[i].uri);
- if (list->resultsReceived[i].meta != NULL)
- ECRS_freeMetaData(list->resultsReceived[i].meta);
- }
- GROW(list->resultsReceived,
- list->sizeResultsReceived,
- 0);
- for (i=0;i<list->sizeUnmatchedResultsReceived;i++) {
- rp = &list->unmatchedResultsReceived[i];
-
- if (rp->fi.uri != NULL)
- ECRS_freeUri(rp->fi.uri);
- if (rp->fi.meta != NULL)
- ECRS_freeMetaData(rp->fi.meta);
- FREENONNULL(rp->matchingKeys);
- }
- GROW(list->resultsReceived,
- list->sizeResultsReceived,
- 0);
- WARN:
- GE_LOG(ectx,
- GE_WARNING | GE_BULK | GE_USER,
- _("FSUI state file `%s' had syntax error at offset %u.\n"),
- fn,
- lseek(fd, 0, SEEK_CUR));
- END:
- CLOSE(fd);
- UNLINK(fn);
- } else {
- if (errno != ENOENT)
- GE_LOG_STRERROR_FILE(ectx,
- GE_WARNING | GE_BULK | GE_USER,
- "open",
- fn);
- }
- } else {
- ret->ipc = NULL;
+/* ******************* STOP code *********************** */
+
+/**
+ * (recursively) signal download suspension.
+ */
+static void signalDownloadSuspend(struct GE_Context * ectx,
+ FSUI_Context * ctx,
+ FSUI_DownloadList * list) {
+ FSUI_Event event;
+ while (list != NULL) {
+ signalDownloadSuspend(ectx,
+ ctx,
+ list->child);
+ event.type = FSUI_download_suspended;
+ event.data.DownloadSuspended.dc.pos = list;
+ event.data.DownloadSuspended.dc.cctx = list->cctx;
+ event.data.DownloadSuspended.dc.ppos = list->parent;
+ event.data.DownloadSuspended.dc.pcctx = list->parent->cctx;
+ ctx->ecb(ctx->ecbClosure, &event);
+ list = list->next;
}
- ret->lock = MUTEX_CREATE(YES);
- ret->cron = cron_create(ectx);
- cron_add_job(ret->cron,
- &updateDownloadThreads,
- 0,
- FSUI_UDT_FREQUENCY,
- ret);
- cron_start(ret->cron);
- return ret;
}
/**
+ * (recursively) free download list
+ */
+static void freeDownloadList(FSUI_DownloadList * list) {
+ FSUI_DownloadList * next;
+
+ while (list != NULL) {
+ freeDownloadList(list->child);
+ /* FIXME: free memory! */
+ next = list->next;
+ FREE(list);
+ list = next;
+ }
+}
+
+/**
* Stop all processes under FSUI control (serialize state, continue
* later if possible).
*/
void FSUI_stop(struct FSUI_Context * ctx) {
struct GE_Context * ectx;
- FSUI_ThreadList * tpos;
FSUI_SearchList * spos;
FSUI_DownloadList * dpos;
FSUI_UnindexList * xpos;
@@ -789,8 +264,6 @@
FSUI_Event event;
void * unused;
int i;
- int fd;
- int big;
ectx = ctx->ectx;
if (ctx->ipc != NULL)
@@ -798,123 +271,89 @@
GE_INFO | GE_REQUEST | GE_USER,
"FSUI shutdown. This may take a while.\n");
+ /* 1) stop everything */
cron_stop(ctx->cron);
cron_del_job(ctx->cron,
&updateDownloadThreads,
FSUI_UDT_FREQUENCY,
ctx);
cron_destroy(ctx->cron);
- /* first, stop all download threads
- by reducing the thread pool size to 0 */
+
+ /* 1a) stop downloading */
ctx->threadPoolSize = 0;
dpos = ctx->activeDownloads.child;
while (dpos != NULL) {
- updateDownloadThread(dpos);
+ FSUI_updateDownloadThread(dpos);
dpos = dpos->next;
}
-
- /* then, wait for all modal threads to complete */
- while (ctx->activeThreads != NULL) {
- tpos = ctx->activeThreads;
- ctx->activeThreads = tpos->next;
- PTHREAD_JOIN(tpos->handle, &unused);
- FREE(tpos);
+ /* 1b) stop searching */
+ spos = ctx->activeSearches;
+ while (spos != NULL) {
+ spos->signalTerminate = YES;
+ PTHREAD_STOP_SLEEP(spos->handle);
+ PTHREAD_JOIN(spos->handle, &unused);
+ spos = spos->next;
}
+ /* 1c) stop unindexing */
+ xpos = ctx->unindexOperations;
+ while (xpos != NULL) {
+ xpos->force_termination = YES;
+ PTHREAD_STOP_SLEEP(xpos->handle);
+ PTHREAD_JOIN(xpos->handle, &unused);
+ xpos = xpos->next;
+ }
+ /* 1d) stop uploading */
+ upos = ctx->activeUploads;
+ while (upos != NULL) {
+ upos->force_termination = YES;
+ PTHREAD_STOP_SLEEP(upos->handle);
+ PTHREAD_JOIN(upos->handle, &unused);
+ upos = upos->next;
+ }
- /* next, serialize all of the FSUI state */
- if (ctx->ipc != NULL) {
- fd = disk_file_open(ectx,
- ctx->name,
- O_CREAT|O_TRUNC|O_WRONLY,
- S_IRUSR|S_IWUSR);
- if (fd != -1) {
- WRITE(fd,
- "FSUI00\n\0",
- 8); /* magic */
- }
-#if DEBUG_PERSISTENCE
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Serializing FSUI state...\n");
-#endif
- } else {
-#if DEBUG_PERSISTENCE
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "NOT serializing FSUI state...\n");
-#endif
- fd = -1;
+ /* 2) signal suspension events */
+ /* 2a) signal search suspension */
+ spos = ctx->activeSearches;
+ while (spos != NULL) {
+ event.type = FSUI_search_suspended;
+ event.data.SearchSuspended.sc.pos = spos;
+ event.data.SearchSuspended.sc.cctx = spos->cctx;
+ ctx->ecb(ctx->ecbClosure, &event);
+ spos = spos->next;
}
- if (fd != -1) {
- if (ctx->collectionData == NULL) {
- WRITEINT(fd, 0);
- } else {
- /* serialize collection data */
- WRITE(fd,
- ctx->collectionData,
- ntohl(ctx->collectionData->size));
- }
+ /* 2b) signal uploads suspension */
+ upos = ctx->activeUploads;
+ while (upos != NULL) {
+ event.type = FSUI_upload_suspended;
+ event.data.UploadSuspended.uc.pos = upos;
+ event.data.UploadSuspended.uc.cctx = upos->cctx;
+ event.data.UploadSuspended.uc.ppos = NULL; /* FIXME */
+ event.data.UploadSuspended.uc.pcctx = NULL; /* FIXME */
+ ctx->ecb(ctx->ecbClosure, &event);
+ upos = upos->next;
}
+ /* 2c) signal downloads suspension */
+ signalDownloadSuspend(ectx,
+ ctx,
+ ctx->activeDownloads.child);
+ /* 2d) signal unindex suspension */
+ xpos = ctx->unindexOperations;
+ while (xpos != NULL) {
+ event.type = FSUI_unindex_suspended;
+ event.data.UnindexSuspended.uc.pos = xpos;
+ event.data.UnindexSuspended.uc.cctx = xpos->cctx;
+ xpos = xpos->next;
+ }
+
+ /* 3) serialize all of the FSUI state */
+ if (ctx->ipc != NULL)
+ FSUI_serialize(ctx);
+
+ /* 4) finally, free memory */
+ /* 4a) free search memory */
while (ctx->activeSearches != NULL) {
spos = ctx->activeSearches;
ctx->activeSearches = spos->next;
-
- spos->signalTerminate = YES;
- PTHREAD_STOP_SLEEP(spos->handle);
- PTHREAD_JOIN(spos->handle, &unused);
- if (fd != -1) {
- /* serialize pending searches */
- char * tmp;
- unsigned int big;
-
- tmp = ECRS_uriToString(spos->uri);
- GE_ASSERT(ectx, tmp != NULL);
- big = htonl(strlen(tmp));
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- WRITE(fd,
- tmp,
- strlen(tmp));
- FREE(tmp);
- big = htonl(spos->anonymityLevel);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- big = htonl(spos->sizeResultsReceived);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- big = htonl(spos->sizeUnmatchedResultsReceived);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- for (i=0;i<spos->sizeResultsReceived;i++)
- writeFileInfo(ectx,
- fd,
- &spos->resultsReceived[i]);
- for (i=0;i<spos->sizeUnmatchedResultsReceived;i++) {
- ResultPending * rp;
-
- rp = &spos->unmatchedResultsReceived[i];
- writeFileInfo(ectx,
- fd,
- &rp->fi);
- big = htonl(rp->matchingKeyCount);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- WRITE(fd,
- rp->matchingKeys,
- sizeof(HashCode512) * rp->matchingKeyCount);
- }
- event.type = FSUI_search_suspending;
- event.data.SearchSuspending.sc.pos = spos;
- event.data.SearchSuspending.sc.cctx = spos->cctx;
- ctx->ecb(ctx->ecbClosure, &event);
- }
-
-
ECRS_freeUri(spos->uri);
for (i=spos->sizeResultsReceived-1;i>=0;i--) {
ECRS_FileInfo * fi;
@@ -927,7 +366,7 @@
0);
for (i=spos->sizeUnmatchedResultsReceived-1;i>=0;i--) {
ResultPending * rp;
-
+
rp = &spos->unmatchedResultsReceived[i];
GROW(rp->matchingKeys,
rp->matchingKeyCount,
@@ -940,77 +379,17 @@
0);
FREE(spos);
}
- if (fd != -1) {
- /* search list terminator */
- big = htonl(0);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- writeDownloadList(ectx,
- fd,
- ctx,
- ctx->activeDownloads.child);
- }
+ /* 4b) free unindex memory */
while (ctx->unindexOperations != NULL) {
xpos = ctx->unindexOperations;
ctx->unindexOperations = xpos->next;
- xpos->force_termination = YES;
- PTHREAD_STOP_SLEEP(xpos->handle);
- PTHREAD_JOIN(xpos->handle, &unused);
- if (fd != -1) {
- WRITEINT(fd, strlen(xpos->filename));
- WRITE(fd,
- xpos->filename,
- strlen(xpos->filename));
- event.type = FSUI_unindex_suspending;
- event.data.UnindexSuspending.uc.pos = xpos;
- event.data.UnindexSuspending.uc.cctx = xpos->cctx;
- ctx->ecb(ctx->ecbClosure, &event);
- }
FREE(xpos->filename);
+ FREE(xpos);
}
- if (fd != -1) {
- /* unindex list terminator */
- big = htonl(0);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- }
+ /* 4c) free upload memory */
while (ctx->activeUploads != NULL) {
- big = htonl(1);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
upos = ctx->activeUploads;
ctx->activeUploads = upos->next;
- upos->force_termination = YES;
- PTHREAD_STOP_SLEEP(upos->handle);
- PTHREAD_JOIN(upos->handle, &unused);
- if (fd != -1) {
- WRITEINT(fd, upos->status);
- WRITELONG(fd, upos->main_completed);
- WRITELONG(fd, upos->main_total);
- WRITELONG(fd, upos->expiration);
- WRITELONG(fd, upos->start_time);
- /* dir track!? */
- writeURI(fd, upos->uri);
- writeURI(fd, upos->globalUri); /* need to handle NULL? */
- WRITESTRING(fd, upos->filename);
- WRITESTRING(fd, upos->main_filename);
- WRITEINT(fd, upos->isRecursive);
- WRITEINT(fd, upos->doIndex);
- WRITEINT(fd, upos->anonymityLevel);
- WRITEINT(fd, upos->priority);
- WRITEINT(fd, upos->individualKeywords);
-
-
- /* FIXME: serialize! */
- event.type = FSUI_upload_suspending;
- event.data.UploadSuspending.uc.pos = upos;
- event.data.UploadSuspending.uc.cctx = upos->cctx;
- event.data.UploadSuspending.uc.ppos = NULL;
- event.data.UploadSuspending.uc.pcctx = NULL;
- }
FREE(upos->filename);
FREENONNULL(upos->main_filename);
ECRS_freeMetaData(upos->meta);
@@ -1020,26 +399,10 @@
EXTRACTOR_removeAll(upos->extractors);
FREE(upos);
}
- if (fd != -1) {
- /* upload list terminator */
- big = htonl(0);
- WRITE(fd,
- &big,
- sizeof(unsigned int));
- }
+ /* 4d) free download memory */
+ freeDownloadList(ctx->activeDownloads.child);
- if (fd != -1) {
-#if DEBUG_PERSISTENCE
- GE_LOG(ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Serializing FSUI state done.\n");
-#endif
- CLOSE(fd);
- }
-
- /* finally, free all (remaining) FSUI data */
- while (ctx->activeDownloads.child != NULL)
- freeDownloadList(ctx->activeDownloads.child);
+ /* 5) finish FSUI Context */
if (ctx->ipc != NULL) {
IPC_SEMAPHORE_UP(ctx->ipc);
IPC_SEMAPHORE_DESTROY(ctx->ipc);
@@ -1054,39 +417,4 @@
}
-/* *************** 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;
- void * unused;
-
- prev = NULL;
- MUTEX_LOCK(ctx->lock);
- pos = ctx->activeThreads;
- while (pos != NULL) {
- if (YES == pos->isDone) {
- PTHREAD_JOIN(pos->handle,
- &unused);
- tmp = pos->next;
- FREE(pos);
- if (prev != NULL)
- prev->next = tmp;
- else
- ctx->activeThreads = tmp;
- pos = tmp;
- } else {
- prev = pos;
- pos = pos->next;
- }
- }
- MUTEX_UNLOCK(ctx->lock);
-}
-
-
/* end of fsui.c */
Modified: GNUnet/src/applications/fs/fsui/fsui.h
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.h 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/fsui.h 2006-10-13 03:09:42 UTC (rev
3482)
@@ -20,7 +20,7 @@
/**
* @file applications/fs/fsui/fsui.h
- * @brief definition of the FSUI_Context
+ * @brief internal definitions for libfsui
* @author Christian Grothoff
*/
#ifndef FSUI_H
@@ -32,30 +32,62 @@
#include "gnunet_blockstore.h"
/**
- * Linked list of FSUI threads.
+ * Current state of a download (or uploads, or search,
+ * or unindex operations).
+ *
+ * PENDING means that the download is waiting for a thread
+ * to be assigned to run it. Downloads start in this state,
+ * and during shutdown are serialized in this state.<br>
+ *
+ * ACTIVE means that there is currently a thread running
+ * the download (and that thread is allowed to continue).<br>
+ *
+ * COMPLETED means that the download is finished (but the
+ * thread has not been joined yet). The download thread
+ * makes the transition from PENDING to COMPLETED when it
+ * is about to terminate.<br>
+ *
+ * COMPLETED_JOINED means that the download is finished and
+ * the thread has been joined.<br>
+ *
+ * ABORTED means that the user is causing the download to be
+ * terminated early (but the thread has not been joined yet). The
+ * controller or the download thread make this transition; the
+ * download thread is supposed to terminate shortly after the state is
+ * moved to ABORTED.<br>
+ *
+ * ABORTED_JOINED means that the download did not complete
+ * successfully, should not be restarted and that the thread
+ * has been joined.<br>
+ *
+ * ERROR means that some fatal error is causing the download to be
+ * terminated early (but the thread has not been joined yet). The
+ * controller or the download thread make this transition; the
+ * download thread is supposed to terminate shortly after the state is
+ * moved to ERROR.<br>
+ *
+ * ERROR_JOINED means that the download did not complete successfully,
+ * should not be restarted and that the thread has been joined.<br>
+ *
+ * SUSPENDING is used to notify the download thread that it
+ * should terminate because of an FSUI shutdown. After this
+ * termination the code that joins the thread should move
+ * the state into PENDING (a new thread would not be started
+ * immediately because "threadPoolSize" will be 0 until FSUI
+ * resumes).
*/
-typedef struct FSUI_ThreadList {
+typedef enum {
+ FSUI_PENDING = 0,
+ FSUI_ACTIVE = 1,
+ FSUI_COMPLETED = 2,
+ FSUI_COMPLETED_JOINED = 3,
+ FSUI_ABORTED = 4,
+ FSUI_ABORTED_JOINED = 5,
+ FSUI_ERROR = 6,
+ FSUI_ERROR_JOINED = 7,
+ FSUI_SUSPENDING = 8,
+} FSUI_State;
- /**
- * FSUI threads are kept in a simple
- * linked list
- */
- struct FSUI_ThreadList * next;
-
- /**
- * Handle to a thread.
- */
- struct PTHREAD * handle;
-
- /**
- * Flag that indicates if it is safe (i.e.
- * non-blocking) to call join on the handle.
- * Set to YES by an FSUI thread upon exit.
- */
- int isDone;
-
-} FSUI_ThreadList;
-
/**
* Track record for a given result.
*/
@@ -147,65 +179,6 @@
} FSUI_SearchList;
/**
- * Current state of a download (or uploads, or search,
- * or unindex operations).
- *
- * PENDING means that the download is waiting for a thread
- * to be assigned to run it. Downloads start in this state,
- * and during shutdown are serialized in this state.<br>
- *
- * ACTIVE means that there is currently a thread running
- * the download (and that thread is allowed to continue).<br>
- *
- * COMPLETED means that the download is finished (but the
- * thread has not been joined yet). The download thread
- * makes the transition from PENDING to COMPLETED when it
- * is about to terminate.<br>
- *
- * COMPLETED_JOINED means that the download is finished and
- * the thread has been joined.<br>
- *
- * ABORTED means that the user is causing the download to be
- * terminated early (but the thread has not been joined yet). The
- * controller or the download thread make this transition; the
- * download thread is supposed to terminate shortly after the state is
- * moved to ABORTED.<br>
- *
- * ABORTED_JOINED means that the download did not complete
- * successfully, should not be restarted and that the thread
- * has been joined.<br>
- *
- * ERROR means that some fatal error is causing the download to be
- * terminated early (but the thread has not been joined yet). The
- * controller or the download thread make this transition; the
- * download thread is supposed to terminate shortly after the state is
- * moved to ERROR.<br>
- *
- * ERROR_JOINED means that the download did not complete successfully,
- * should not be restarted and that the thread has been joined.<br>
- *
- * SUSPENDING is used to notify the download thread that it
- * should terminate because of an FSUI shutdown. After this
- * termination the code that joins the thread should move
- * the state into PENDING (a new thread would not be started
- * immediately because "threadPoolSize" will be 0 until FSUI
- * resumes).
- */
-typedef enum {
- FSUI_PENDING = 0,
- FSUI_ACTIVE = 1,
- FSUI_COMPLETED = 2,
- FSUI_COMPLETED_JOINED = 3,
- FSUI_ABORTED = 4,
- FSUI_ABORTED_JOINED = 5,
- FSUI_ERROR = 6,
- FSUI_ERROR_JOINED = 7,
- FSUI_SUSPENDING = 8,
-} FSUI_State;
-
-
-
-/**
* @brief list of active downloads
*/
typedef struct FSUI_DownloadList {
@@ -222,11 +195,6 @@
unsigned long long completed;
/**
- * How many bytes have been retrieved so far for this particular file only.
- */
- unsigned long long completedFile;
-
- /**
* URI for this download.
*/
struct ECRS_URI * uri;
@@ -278,11 +246,21 @@
/**
* 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.
+ * absolute start time.<p>
+ * While the download thread is running, this is the
+ * absolute start time assuming the thread ran continuously.
*/
cron_t startTime;
/**
+ * While the download thread is suspended, this is the
+ * total amount of time that all threads have consumed so far.
+ * While the download thread is running, startTime should
+ * be used instead (since runTime maybe outdated).
+ */
+ cron_t runTime;
+
+ /**
* Is this a recursive download? (YES/NO)
*/
int is_recursive;
@@ -355,6 +333,8 @@
/**
* Context for the upload thread.
+ *
+ * TODO: keep upload hierarchy!
*/
typedef struct FSUI_UploadList {
@@ -448,12 +428,6 @@
DataContainer * collectionData;
/**
- * Active FSUI threads that cannot be stopped and
- * that FSUI must call join on before it may shutdown.
- */
- FSUI_ThreadList * activeThreads;
-
- /**
* List of active searches.
*/
FSUI_SearchList * activeSearches;
@@ -485,6 +459,8 @@
} FSUI_Context;
+/* ************ cross-file prototypes ************ */
+
/**
* Starts or stops download threads in accordance with thread pool
* size and active downloads. Call only while holding FSUI lock (or
@@ -492,31 +468,16 @@
*
* @return YES if change done that may require re-trying
*/
-int updateDownloadThread(FSUI_DownloadList * list);
+int FSUI_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);
+void * FSUI_uploadThread(void * dl);
-/**
- * Cleanup the FSUI context (removes dead entries from
- * activeThreads / activeSearches / activeDownloads).
- */
-void cleanupFSUIThreadList(FSUI_Context * ctx);
+void * FSUI_searchThread(void * pos);
+void * FSUI_unindexThread(void * cls);
-/* FOR RESUME: from download.c */
-/**
- * Thread that downloads a file.
- */
-void * downloadThread(void * dl);
+void FSUI_serialize(struct FSUI_Context * ctx);
-/* from search.c */
-/**
- * FOR RESUME: Thread that searches for data.
- */
-void * searchThread(void /* FSUI_SearchList */ * pos);
+void FSUI_deserialize(struct FSUI_Context * ctx);
#endif
Modified: GNUnet/src/applications/fs/fsui/search.c
===================================================================
--- GNUnet/src/applications/fs/fsui/search.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/search.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -240,7 +240,7 @@
/**
* Thread that searches for data.
*/
-void * searchThread(void * cls) {
+void * FSUI_searchThread(void * cls) {
FSUI_SearchList * pos = cls;
ECRS_search(pos->ctx->ectx,
pos->ctx->cfg,
@@ -276,7 +276,7 @@
pos->unmatchedResultsReceived = 0;
pos->anonymityLevel = anonymityLevel;
pos->ctx = ctx;
- pos->handle = PTHREAD_CREATE(&searchThread,
+ pos->handle = PTHREAD_CREATE(&FSUI_searchThread,
pos,
32 * 1024);
if (pos->handle == NULL) {
Added: GNUnet/src/applications/fs/fsui/serialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serialize.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/serialize.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -0,0 +1,275 @@
+/*
+ This file is part of GNUnet.
+ (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other
contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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.
+*/
+
+
+/**
+ * @file applications/fs/fsui/serialize.c
+ * @brief FSUI functions for writing state to disk
+ * @author Christian Grothoff
+ * @see deserializer.c
+ *
+ * TODO:
+ * - upload tree handling (need to change upload representation)
+ */
+
+#include "platform.h"
+#include "gnunet_fsui_lib.h"
+#include "gnunet_directories.h"
+#include "fsui.h"
+
+static void WRITEINT(int fd,
+ int val) {
+ int big;
+ big = htonl(val);
+ WRITE(fd, &big, sizeof(int));
+}
+
+static void WRITELONG(int fd,
+ long long val) {
+ long long big;
+ big = htonll(val);
+ WRITE(fd, &big, sizeof(long long));
+}
+
+static void writeURI(int fd,
+ const struct ECRS_URI * uri) {
+ char * buf;
+ unsigned int size;
+
+ buf = ECRS_uriToString(uri);
+ size = strlen(buf);
+ WRITEINT(fd, size);
+ WRITE(fd,
+ buf,
+ size);
+ FREE(buf);
+}
+
+static void WRITESTRING(int fd,
+ const char * name) {
+ WRITEINT(fd,
+ strlen(name));
+ WRITE(fd,
+ name,
+ strlen(name));
+}
+
+/**
+ * (recursively) write a download list.
+ */
+static void writeDownloadList(struct GE_Context * ectx,
+ int fd,
+ FSUI_Context * ctx,
+ FSUI_DownloadList * list) {
+ int i;
+
+ if (list == NULL) {
+ WRITEINT(fd, 0);
+ return;
+ }
+#if DEBUG_PERSISTENCE
+ GE_LOG(ectx,
+ GE_DEBUG | GE_REQUEST | GE_USER,
+ "Serializing download state of download `%s': (%llu, %llu)\n",
+ list->filename,
+ list->completed,
+ list->total);
+#endif
+ WRITEINT(fd, 1);
+ WRITEINT(fd, list->state);
+ WRITEINT(fd, list->is_recursive);
+ WRITEINT(fd, list->is_directory);
+ WRITEINT(fd, list->anonymityLevel);
+ WRITEINT(fd, list->completedDownloadsCount);
+ WRITELONG(fd, list->total);
+ WRITELONG(fd, list->completed);
+ WRITELONG(fd, get_time() - list->startTime);
+ WRITESTRING(fd, list->filename);
+ writeURI(fd, list->uri);
+ for (i=0;i<list->completedDownloadsCount;i++)
+ writeURI(fd, list->completedDownloads[i]);
+ writeDownloadList(ectx,
+ fd,
+ ctx,
+ list->next);
+ writeDownloadList(ectx,
+ fd,
+ ctx,
+ list->child);
+}
+
+
+static void writeFileInfo(struct GE_Context * ectx,
+ int fd,
+ const ECRS_FileInfo * fi) {
+ unsigned int size;
+ char * buf;
+
+ size = ECRS_sizeofMetaData(fi->meta,
+ ECRS_SERIALIZE_FULL | ECRS_SERIALIZE_NO_COMPRESS);
+ if (size > 1024 * 1024)
+ size = 1024 * 1024;
+ buf = MALLOC(size);
+ ECRS_serializeMetaData(ectx,
+ fi->meta,
+ buf,
+ size,
+ ECRS_SERIALIZE_PART | ECRS_SERIALIZE_NO_COMPRESS);
+ WRITEINT(fd, size);
+ WRITE(fd,
+ buf,
+ size);
+ FREE(buf);
+ writeURI(fd, fi->uri);
+}
+
+static void writeCollection(int fd,
+ struct FSUI_Context * ctx) {
+ if ( (ctx->collectionData == NULL) ||
+ (ctx->collectionData->size > 16 * 1024 * 1024) ) {
+ WRITEINT(fd, 0);
+ return;
+ }
+ /* serialize collection data */
+ WRITE(fd,
+ ctx->collectionData,
+ ntohl(ctx->collectionData->size));
+}
+
+static void writeSearches(int fd,
+ struct FSUI_Context * ctx) {
+ char * tmp;
+ FSUI_SearchList * spos;
+ int i;
+
+ spos = ctx->activeSearches;
+ while (spos != NULL) {
+ if ( (spos->sizeResultsReceived > 1024 * 1024) ||
+ (spos->sizeUnmatchedResultsReceived > 1024 * 1024) ) {
+ /* too large to serialize - skip! */
+ spos = spos->next;
+ continue;
+ }
+ GE_ASSERT(ctx->ectx,
+ spos->signalTerminate == YES);
+ GE_ASSERT(ctx->ectx,
+ ECRS_isKeywordUri(spos->uri));
+ WRITEINT(fd, 1);
+ WRITEINT(fd, spos->state);
+ WRITEINT(fd, spos->anonymityLevel);
+ WRITEINT(fd, spos->sizeResultsReceived);
+ WRITEINT(fd, spos->sizeUnmatchedResultsReceived);
+ tmp = ECRS_uriToString(spos->uri);
+ GE_ASSERT(NULL, tmp != NULL);
+ WRITESTRING(fd, tmp);
+ FREE(tmp);
+ for (i=0;i<spos->sizeResultsReceived;i++)
+ writeFileInfo(ctx->ectx,
+ fd,
+ &spos->resultsReceived[i]);
+ for (i=0;i<spos->sizeUnmatchedResultsReceived;i++) {
+ ResultPending * rp;
+
+ rp = &spos->unmatchedResultsReceived[i];
+ writeFileInfo(ctx->ectx,
+ fd,
+ &rp->fi);
+ GE_ASSERT(ctx->ectx,
+ rp->matchingKeyCount < spos->numberOfURIKeys);
+ if (rp->matchingKeyCount > 1024) {
+ WRITEINT(fd, 0); /* too large to serialize */
+ continue;
+ }
+ WRITEINT(fd, rp->matchingKeyCount);
+ WRITE(fd,
+ rp->matchingKeys,
+ sizeof(HashCode512) * rp->matchingKeyCount);
+ }
+ spos = spos->next;
+ }
+ WRITEINT(fd, 0);
+}
+
+static void writeUnindexing(int fd,
+ struct FSUI_Context * ctx) {
+ FSUI_UnindexList * xpos;
+
+
+ xpos = ctx->unindexOperations;
+ while (xpos != NULL) {
+ WRITEINT(fd, 1);
+ WRITEINT(fd, xpos->state);
+ WRITESTRING(fd, xpos->filename);
+ xpos = xpos->next;
+ }
+ /* unindex list terminator */
+ WRITEINT(fd, 0);
+}
+
+static void writeUploads(int fd,
+ struct FSUI_Context * ctx) {
+ FSUI_UploadList * upos;
+
+ upos = ctx->activeUploads;
+ while (upos != NULL) {
+ WRITEINT(fd, 1);
+ WRITEINT(fd, upos->state);
+ WRITELONG(fd, upos->main_completed);
+ WRITELONG(fd, upos->main_total);
+ WRITELONG(fd, upos->expiration);
+ WRITELONG(fd, upos->start_time);
+ writeURI(fd, upos->uri);
+ writeURI(fd, upos->globalUri); /* need to handle NULL? */
+ WRITESTRING(fd, upos->filename);
+ WRITESTRING(fd, upos->main_filename);
+ WRITEINT(fd, upos->isRecursive);
+ WRITEINT(fd, upos->doIndex);
+ WRITEINT(fd, upos->anonymityLevel);
+ WRITEINT(fd, upos->priority);
+ WRITEINT(fd, upos->individualKeywords);
+ upos = upos->next;
+ }
+ WRITEINT(fd, 0);
+}
+
+void FSUI_serialize(struct FSUI_Context * ctx) {
+ int fd;
+
+ fd = disk_file_open(ctx->ectx,
+ ctx->name,
+ O_CREAT|O_TRUNC|O_WRONLY,
+ S_IRUSR|S_IWUSR);
+ if (fd == -1)
+ return;
+ WRITE(fd,
+ "FSUI01\n\0",
+ 8); /* magic */
+ writeCollection(fd, ctx);
+ writeSearches(fd, ctx);
+ writeDownloadList(ctx->ectx,
+ fd,
+ ctx,
+ ctx->activeDownloads.child);
+ writeUnindexing(fd, ctx);
+ writeUploads(fd, ctx);
+ CLOSE(fd);
+}
+
+/* end of serializer */
Property changes on: GNUnet/src/applications/fs/fsui/serialize.c
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: GNUnet/src/applications/fs/fsui/unindex.c
===================================================================
--- GNUnet/src/applications/fs/fsui/unindex.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/unindex.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -65,7 +65,7 @@
/**
* Thread that does the unindex.
*/
-static void * unindexThread(void * cls) {
+void * FSUI_unindexThread(void * cls) {
FSUI_UnindexList * utc = cls;
FSUI_Event event;
int ret;
@@ -81,12 +81,12 @@
event.type = FSUI_unindex_complete;
if (OK != disk_file_size(utc->ctx->ectx,
utc->filename,
- &event.data.UnindexComplete.total,
+ &event.data.UnindexCompleted.total,
YES)) {
GE_BREAK(utc->ctx->ectx, 0);
- event.data.UnindexComplete.total = 0;
+ event.data.UnindexCompleted.total = 0;
}
- event.data.UnindexComplete.filename = utc->filename;
+ event.data.UnindexCompleted.filename = utc->filename;
} else {
event.type = FSUI_unindex_error;
event.data.UnindexError.message = _("Unindex failed.");
@@ -131,7 +131,7 @@
utc->filename = STRDUP(filename);
utc->start_time = get_time();
utc->force_termination = NO;
- utc->handle = PTHREAD_CREATE(&unindexThread,
+ utc->handle = PTHREAD_CREATE(&FSUI_unindexThread,
utc,
32 * 1024);
if (utc->handle == NULL) {
Modified: GNUnet/src/applications/fs/fsui/upload.c
===================================================================
--- GNUnet/src/applications/fs/fsui/upload.c 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/applications/fs/fsui/upload.c 2006-10-13 03:09:42 UTC (rev
3482)
@@ -154,12 +154,11 @@
if (ret == OK) {
GE_ASSERT(ectx, NULL != *uri);
event.type = FSUI_upload_complete;
- event.data.UploadComplete.total = utc->main_total;
- event.data.UploadComplete.filename = STRDUP(dirName);
- event.data.UploadComplete.uri = *uri;
+ event.data.UploadCompleted.total = utc->main_total;
+ event.data.UploadCompleted.filename = dirName;
+ event.data.UploadCompleted.uri = *uri;
utc->ctx->ecb(utc->ctx->ecbClosure,
&event);
- FREE(event.data.UploadComplete.filename);
utc->main_completed += len;
}
UNLINK(tempName);
@@ -214,9 +213,9 @@
if (ret == OK) {
GE_ASSERT(ectx, uri != NULL);
event.type = FSUI_upload_complete;
- event.data.UploadComplete.total = utc->main_total;
- event.data.UploadComplete.filename = utc->filename;
- event.data.UploadComplete.uri = uri;
+ event.data.UploadCompleted.total = utc->main_total;
+ event.data.UploadCompleted.filename = utc->filename;
+ event.data.UploadCompleted.uri = uri;
if (OK == disk_file_size(ectx,
fn,
&len,
@@ -332,7 +331,7 @@
/**
* Thread that does the upload.
*/
-static void * uploadThread(void * cls) {
+void * FSUI_uploadThread(void * cls) {
FSUI_UploadList * utc = cls;
struct ECRS_URI * uri;
struct ECRS_URI * keywordUri;
@@ -378,9 +377,9 @@
&uri);
if (ret == OK) {
event.type = FSUI_upload_complete;
- event.data.UploadComplete.total = utc->main_total;
- event.data.UploadComplete.filename = utc->filename;
- event.data.UploadComplete.uri = uri;
+ event.data.UploadCompleted.total = utc->main_total;
+ event.data.UploadCompleted.filename = utc->filename;
+ event.data.UploadCompleted.uri = uri;
} else {
event.type = FSUI_upload_error;
event.data.UploadError.message = _("Upload failed.");
@@ -556,7 +555,7 @@
utc->doIndex = doIndex;
utc->individualKeywords = NO;
utc->force_termination = NO;
- utc->handle = PTHREAD_CREATE(&uploadThread,
+ utc->handle = PTHREAD_CREATE(&FSUI_uploadThread,
utc,
128 * 1024);
if (utc->handle == NULL) {
@@ -575,7 +574,6 @@
utc->next = ctx->activeUploads;
ctx->activeUploads = utc;
MUTEX_UNLOCK(ctx->lock);
- cleanupFSUIThreadList(ctx);
return utc;
}
Modified: GNUnet/src/applications/fs/tools/gnunet-download.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-download.c 2006-10-12 20:51:47 UTC
(rev 3481)
+++ GNUnet/src/applications/fs/tools/gnunet-download.c 2006-10-13 03:09:42 UTC
(rev 3482)
@@ -25,6 +25,7 @@
*/
#include "platform.h"
+#include "gnunet_directories.h"
#include "gnunet_fsui_lib.h"
#include "gnunet_util_config_impl.h"
#include "gnunet_util_error_loggers.h"
@@ -37,14 +38,12 @@
static int do_recursive;
-static char * cfgFilename;
+static char * cfgFilename = DEFAULT_CLIENT_CONFIG_FILE;
static char * filename;
static unsigned int anonymity = 1;
-static struct SEMAPHORE * signalFinished;
-
static cron_t start_time;
static struct FSUI_DownloadList * dl;
@@ -96,21 +95,14 @@
case FSUI_download_aborted:
if (dl == event->data.DownloadError.dc.pos) {
/* 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? */
+ PRINTF(_("Download aborted.\n"));
}
break;
case FSUI_download_error:
printf(_("Error downloading: %s\n"),
event->data.DownloadError.message);
*ok = SYSERR;
- SEMAPHORE_UP(signalFinished);
+ GNUNET_SHUTDOWN_INITIATE();
break;
case FSUI_download_complete:
if ( (event->data.DownloadProgress.completed ==
@@ -123,7 +115,7 @@
/ (double)cronSECONDS) );
if (dl == event->data.DownloadProgress.dc.pos) {
*ok = OK;
- SEMAPHORE_UP(signalFinished);
+ GNUNET_SHUTDOWN_INITIATE();
}
}
break;
@@ -164,12 +156,13 @@
gnunetdownloadOptions,
(unsigned int) argc,
argv);
- if (i == SYSERR) {
+ if ( (i == SYSERR) ||
+ (0 != GC_parse_configuration(cfg,
+ cfgFilename)) ) {
GC_free(cfg);
GE_free_context(ectx);
return -1;
}
-
if (i == argc) {
GE_LOG(ectx,
GE_WARNING | GE_BULK | GE_USER,
@@ -215,7 +208,7 @@
filename);
try_rename = YES;
}
- signalFinished = SEMAPHORE_CREATE(0);
+ ok = NO;
ctx = FSUI_start(ectx,
cfg,
"gnunet-download",
@@ -229,14 +222,14 @@
do_recursive,
uri,
filename);
- /* FIXME: use gnunetutil shutdown management instead! */
- if (dl != NULL)
- SEMAPHORE_DOWN(signalFinished, YES);
+ GNUNET_SHUTDOWN_WAITFOR();
+ if (OK != ok)
+ FSUI_abortDownload(ctx, dl);
FSUI_stopDownload(ctx, dl);
FSUI_stop(ctx);
- SEMAPHORE_DESTROY(signalFinished);
- if ( (dl != NULL) &&
+ if ( (OK == ok) &&
+ (dl != NULL) &&
(try_rename == YES) ) {
char * newname = ECRS_suggestFilename(ectx,
filename);
@@ -252,7 +245,7 @@
ECRS_freeUri(uri);
GC_free(cfg);
GE_free_context(ectx);
- if (dl == NULL)
+ if (ok != OK)
return 1;
return 0;
}
Modified: GNUnet/src/applications/fs/tools/gnunet-insert.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-insert.c 2006-10-12 20:51:47 UTC
(rev 3481)
+++ GNUnet/src/applications/fs/tools/gnunet-insert.c 2006-10-13 03:09:42 UTC
(rev 3482)
@@ -177,21 +177,21 @@
delta = get_time() - start_time;
PRINTF(_("Upload of `%s' complete, "
"%llu bytes took %llu seconds (%8.3f KiB/s).\n"),
- event->data.UploadComplete.filename,
- event->data.UploadComplete.total,
+ event->data.UploadCompleted.filename,
+ event->data.UploadCompleted.total,
delta / cronSECONDS,
(delta == 0)
? (double) (-1.0)
- : (double) (event->data.UploadComplete.total
+ : (double) (event->data.UploadCompleted.total
/ 1024.0 * cronSECONDS / delta));
}
- fstring = ECRS_uriToString(event->data.UploadComplete.uri);
+ fstring = ECRS_uriToString(event->data.UploadCompleted.uri);
printf(_("File `%s' has URI: %s\n"),
- event->data.UploadComplete.filename,
+ event->data.UploadCompleted.filename,
fstring);
FREE(fstring);
- if (ul == event->data.UploadComplete.uc.pos) {
- postProcess(event->data.UploadComplete.uri);
+ if (ul == event->data.UploadCompleted.uc.pos) {
+ postProcess(event->data.UploadCompleted.uri);
if (exitSignal != NULL)
SEMAPHORE_UP(exitSignal);
}
Modified: GNUnet/src/applications/fs/tools/gnunet-unindex.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-unindex.c 2006-10-12 20:51:47 UTC
(rev 3481)
+++ GNUnet/src/applications/fs/tools/gnunet-unindex.c 2006-10-13 03:09:42 UTC
(rev 3482)
@@ -70,12 +70,12 @@
delta = get_time() - start_time;
PRINTF(
_("\nUnindexing of `%s' complete, %llu bytes took %llu seconds (%8.3f
KiB/s).\n"),
- event->data.UnindexComplete.filename,
- event->data.UnindexComplete.total,
+ event->data.UnindexCompleted.filename,
+ event->data.UnindexCompleted.total,
delta / cronSECONDS,
(delta == 0)
? (double) (-1.0)
- : (double) (event->data.UnindexComplete.total / 1024.0 * cronSECONDS /
delta));
+ : (double) (event->data.UnindexCompleted.total / 1024.0 * cronSECONDS /
delta));
}
SEMAPHORE_UP(exitSignal);
break;
Modified: GNUnet/src/include/gnunet_fsui_lib.h
===================================================================
--- GNUnet/src/include/gnunet_fsui_lib.h 2006-10-12 20:51:47 UTC (rev
3481)
+++ GNUnet/src/include/gnunet_fsui_lib.h 2006-10-13 03:09:42 UTC (rev
3482)
@@ -31,15 +31,17 @@
* event processor also may have to worry about synchronizing itself
* with the GUI library to display updates).<p>
*
- * After creating a FSUI_Context with FSUI_start the UI can start (or
- * cancel) uploads, downloads or searches. The FSUI_Context can be
- * destroyed, when it is created again the next time all pending
- * operations are resumed (!). Clients can use the various iterator
- * functions to obtain information about pending actions.<p>
+ * After creating a FSUI_Context with FSUI_start the UI can start,
+ * abort and stop uploads, downloads, deletions or searches.
+ * The FSUI_Context can be destroyed, when it is created again
+ * the next time all pending operations are resumed (!).
+ * Clients can use the various iterator functions to obtain
+ * information about pending actions.<p>
*
- * Note that there can only be one FSUI_Context for all clients.
+ * Note that there can only be one FSUI_Context for a given
+ * client application name if resuming is enabled.
* Creating an FSUI_Context may _fail_ if any other UI is currently
- * running (for the same user).<p>
+ * running (for the same user and application name).<p>
*
* Clients may use SOME functions of GNUnet's ECRS library, in
* particular functions to deal with URIs and MetaData, but generally
@@ -54,8 +56,20 @@
* unindexing operations have completed before attempting to close
* the FSUI_Context.<p>
*
+ * Any "startXXX" operation will result in FSUI state and memory
+ * being allocated until it is paired with a "stopXXX" operation.
+ * Before calling "stopXXX", one of three things must happen:
+ * Either, the client receives an "error" (something went wrong)
+ * or "completed" (action finished) event. Alternatively, the
+ * client may call abortXXX" which will result in an "aborted"
+ * event. In either case, the event itself will NOT result in
+ * the action being "forgotten" by FSUI -- the client must still
+ * call "FSUI_stopXXX" explicitly. Clients that call
+ * "FSUI_stopXXX" before an aborted, error or completed event
+ * will be blocked until either of the three events happens.<p>
+ *
* Note that most of this code is completely new in GNUnet 0.7.0 and
- * thus still highly experimental. Suggestions are welcome.
+ * thus still highly experimental. Suggestions are welcome.<p>
*/
#ifndef GNUNET_FSUI_LIB_H
@@ -95,7 +109,8 @@
*
* For the types aborted, error, suspending and complete,
* the client MUST free the "cctx" context associated with
- * the event (if allocated).<p>
+ * the event (if allocated). This context is created
+ * by the "resume" operation.<p>
*
* Resume events are issued when operations resume as well
* as when they are first initiated!<p>
@@ -104,31 +119,38 @@
* number of results has been found.
*/
enum FSUI_EventType {
-
+ FSUI_search_started,
+ FSUI_search_stopped,
FSUI_search_result,
FSUI_search_completed,
FSUI_search_aborted,
FSUI_search_error,
- FSUI_search_suspending,
- FSUI_search_resuming,
+ FSUI_search_suspended,
+ FSUI_search_resumed,
+ FSUI_download_started,
+ FSUI_download_stopped,
FSUI_download_progress,
FSUI_download_complete,
FSUI_download_aborted,
FSUI_download_error,
- FSUI_download_suspending,
- FSUI_download_resuming,
+ FSUI_download_suspended,
+ FSUI_download_resumed,
+ FSUI_upload_started,
+ FSUI_upload_stopped,
FSUI_upload_progress,
FSUI_upload_complete,
FSUI_upload_aborted,
FSUI_upload_error,
- FSUI_upload_suspending,
- FSUI_upload_resuming,
+ FSUI_upload_suspended,
+ FSUI_upload_resumed,
+ FSUI_unindex_started,
+ FSUI_unindex_stopped,
FSUI_unindex_progress,
FSUI_unindex_complete,
FSUI_unindex_aborted,
FSUI_unindex_error,
- FSUI_unindex_suspending,
- FSUI_unindex_resuming,
+ FSUI_unindex_suspended,
+ FSUI_unindex_resumed,
/**
* Connection status with gnunetd changed.
*/
@@ -223,55 +245,69 @@
* The URI of the search for which data was
* found.
*/
- struct ECRS_URI * searchURI;
+ const struct ECRS_URI * searchURI;
} SearchResult;
struct {
- struct FSUI_SearchList * pos;
+ FSUI_SearchContext sc;
} SearchCompleted;
struct {
- struct FSUI_SearchList * pos;
+ FSUI_SearchContext sc;
} SearchAborted;
-
struct {
FSUI_SearchContext sc;
+
+ const char * message;
- char * message;
-
} SearchError;
+ struct {
+ FSUI_SearchContext sc;
+
+ } SearchSuspended;
+
struct {
FSUI_SearchContext sc;
- } SearchSuspending;
+ struct ECRS_URI * searchURI;
+ const ECRS_FileInfo * fis;
+ unsigned int anonymityLevel;
+
+ unsigned int fisSize;
+
+ } SearchResumed;
+
struct {
FSUI_SearchContext sc;
- ECRS_FileInfo * fis;
+ const struct ECRS_URI * searchURI;
- unsigned int fisSize;
-
unsigned int anonymityLevel;
- struct ECRS_URI * searchURI;
+ } SearchStarted;
- } SearchResuming;
+ struct {
+ FSUI_SearchContext sc;
+
+ } SearchStopped;
+
+
struct {
FSUI_DownloadContext dc;
@@ -300,12 +336,12 @@
/**
* Information about the download.
*/
- char * filename;
+ const char * filename;
/**
* Original URI.
*/
- struct ECRS_URI * uri;
+ const struct ECRS_URI * uri;
/**
* The last block (in plaintext)
@@ -333,14 +369,14 @@
/**
* Information about the download.
*/
- char * filename;
+ const char * filename;
/**
* Original URI.
*/
- struct ECRS_URI * uri;
+ const struct ECRS_URI * uri;
- } DownloadComplete;
+ } DownloadCompleted;
struct {
@@ -366,14 +402,45 @@
FSUI_DownloadContext dc;
- } DownloadSuspending;
+ } DownloadStopped;
struct {
FSUI_DownloadContext dc;
+ } DownloadSuspended;
+
+
+ struct {
+
+ FSUI_DownloadContext dc;
+
/**
+ * How large is the total download (as far
+ * as known so far).
+ */
+ unsigned long long total;
+
+ /**
+ * Information about the download.
+ */
+ const char * filename;
+
+ /**
+ * Original URI.
+ */
+ const struct ECRS_URI * uri;
+
+ unsigned int anonymityLevel;
+
+ } DownloadStarted;
+
+ struct {
+
+ FSUI_DownloadContext dc;
+
+ /**
* How far are we?
*/
unsigned long long completed;
@@ -392,18 +459,18 @@
/**
* Information about the download.
*/
- char * filename;
+ const char * filename;
- unsigned int anonymityLevel;
-
/**
* Original URI.
*/
- struct ECRS_URI * uri;
+ const struct ECRS_URI * uri;
- } DownloadResuming;
+ unsigned int anonymityLevel;
+ } DownloadResumed;
+
struct {
FSUI_UploadContext uc;
@@ -426,7 +493,7 @@
/**
* Information about the upload.
*/
- char * filename;
+ const char * filename;
} UploadProgress;
@@ -443,14 +510,14 @@
/**
* Which file was uploaded?
*/
- char * filename;
+ const char * filename;
/**
* URI of the uploaded file.
*/
struct ECRS_URI * uri;
- } UploadComplete;
+ } UploadCompleted;
struct {
@@ -464,16 +531,21 @@
FSUI_UploadContext uc;
- char * message;
+ const char * message;
} UploadError;
+ struct {
+ FSUI_UploadContext uc;
+
+ } UploadSuspended;
+
struct {
FSUI_UploadContext uc;
- } UploadSuspending;
+ } UploadStopped;
struct {
@@ -481,6 +553,24 @@
FSUI_UploadContext uc;
/**
+ * How large is the total upload (for the current file)
+ */
+ unsigned long long total;
+
+ unsigned int anonymityLevel;
+
+ /**
+ * Information about the upload.
+ */
+ const char * filename;
+
+ } UploadStarted;
+
+ struct {
+
+ FSUI_UploadContext uc;
+
+ /**
* How far are we? (for the current file)
*/
unsigned long long completed;
@@ -500,9 +590,9 @@
/**
* Information about the upload.
*/
- char * filename;
+ const char * filename;
- } UploadResuming;
+ } UploadResumed;
struct {
@@ -515,7 +605,7 @@
cron_t eta;
- char * filename;
+ const char * filename;
} UnindexProgress;
@@ -526,9 +616,9 @@
unsigned long long total;
- char * filename;
+ const char * filename;
- } UnindexComplete;
+ } UnindexCompleted;
struct {
@@ -537,12 +627,18 @@
} UnindexAborted;
+ struct {
+ FSUI_UnindexContext uc;
+
+ } UnindexStopped;
+
+
struct {
FSUI_UnindexContext uc;
- } UnindexSuspending;
+ } UnindexSuspended;
struct {
@@ -554,18 +650,28 @@
unsigned long long completed;
cron_t eta;
+
+ const char * filename;
- char * filename;
+ } UnindexResumed;
- } UnindexResuming;
+ struct {
+ FSUI_UnindexContext uc;
+
+ unsigned long long total;
+
+ const char * filename;
+ } UnindexStarted;
+
+
struct {
FSUI_UnindexContext uc;
+
+ const char * message;
- char * message;
-
} UnindexError;
} data;
@@ -651,6 +757,14 @@
const struct ECRS_URI * uri); /* search.c */
/**
+ * Abort a search.
+ *
+ * @return SYSERR if such a search is not known
+ */
+int FSUI_abortSearch(struct FSUI_Context * ctx,
+ struct FSUI_SearchList * sl); /* search.c */
+
+/**
* Stop a search.
*
* @return SYSERR if such a search is not known
@@ -676,6 +790,15 @@
*
* @return SYSERR on error
*/
+int FSUI_abortDownload(struct FSUI_Context * ctx,
+ struct FSUI_DownloadList * dl); /* download.c */
+
+/**
+ * Stop a download. If the dl is for a recursive
+ * download, all sub-downloads will also be stopped.
+ *
+ * @return SYSERR on error
+ */
int FSUI_stopDownload(struct FSUI_Context * ctx,
struct FSUI_DownloadList * dl); /* download.c */
@@ -712,6 +835,15 @@
*
* @return SYSERR on error
*/
+int FSUI_abortUpload(struct FSUI_Context * ctx,
+ struct FSUI_UploadList * ul);
+
+/**
+ * Stop an upload. If the context is for a recursive
+ * upload, all sub-uploads will also be stopped.
+ *
+ * @return SYSERR on error
+ */
int FSUI_stopUpload(struct FSUI_Context * ctx,
struct FSUI_UploadList * ul);
@@ -733,6 +865,16 @@
*
* @return SYSERR on error
*/
+int FSUI_abortUnindex(struct FSUI_Context * ctx,
+ struct FSUI_UnindexList * ul);
+
+
+/**
+ * Stop an unindex operation. If the context is for a recursive
+ * upload, all sub-uploads will also be stopped.
+ *
+ * @return SYSERR on error
+ */
int FSUI_stopUnindex(struct FSUI_Context * ctx,
struct FSUI_UnindexList * ul);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r3482 - in GNUnet/src: applications/fs/fsui applications/fs/tools include,
grothoff <=