summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-07-01 13:07:39 +0200
committerYorhel <git@yorhel.nl>2013-07-01 13:10:34 +0200
commit40b54d22cb9b933cacecece750a0b5b7633c83a5 (patch)
tree540722525146fc10ce0a68fe3367266749c4fd87
parent2c11d2afa83f9ece481d99b6f253e708fb2eafdb (diff)
share/hash: Queue (still empty) hash jobs + remove 'cancelled' flag
I had already planned to use fn->fl == NULL to indicate cancelled state, which kinda make sense because in most cases that pointer would be dangling after cancellation. The only situation where this isn't the case is when hashing is "cancelled" after a hash job failed with an error, but it's handled pretty much the same.
-rw-r--r--src/share/hash.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/src/share/hash.c b/src/share/hash.c
index cc04c92..74925d3 100644
--- a/src/share/hash.c
+++ b/src/share/hash.c
@@ -58,8 +58,8 @@
typedef struct {
/* w.data = the share_hash_fn_t struct. */
evtp_work_t w;
- int chunk_start;
- int chunk_num;
+ uint16_t chunk_start;
+ uint16_t chunk_num; /* set to 0 on read() error */
} share_hash_work_t;
@@ -77,7 +77,6 @@ typedef struct {
uint16_t chunknum;
uint8_t jobnum;
uint8_t idx;
- bool cancelled;
int fd;
share_hash_work_t work[HASH_JOBS_PER_FILE];
evtp_work_t openw;
@@ -114,12 +113,13 @@ static void share_hash_fn_destroy(share_hash_fn_t *fn) {
/* close() is assumed to not block for read-only file descriptors */
if(fn->fd >= 0)
close(fn->fd);
+ free(fn->chunks);
free(fn);
}
static void share_hash_fn_cancel(share_hash_fn_t *fn) {
- fn->cancelled = true;
+ fn->fl = NULL;
if(obj->fns[fn->idx] == fn)
obj->fns[fn->idx] = NULL;
@@ -132,15 +132,47 @@ static void share_hash_fn_cancel(share_hash_fn_t *fn) {
}
+static void share_hash_fn_done(evtp_work_t *w) {
+ share_hash_fn_t *fn = w->data;
+ fn->jobnum--;
+ obj->jobs--;
+
+ /* Consider this hash as cancelled if a worker has failed.
+ * TODO: the file object should be removed from the tree. */
+ size_t job = ((share_hash_work_t *)w) - fn->work;
+ if(!fn->work[job].chunk_num)
+ share_hash_fn_cancel(fn);
+
+ /* Wait until all jobs have finished */
+ if(fn->jobnum > 0)
+ return;
+
+ if(!fn->fl) {
+ share_hash_fn_destroy(fn);
+ return;
+ }
+
+ /* TODO:
+ * - Calculate root hash
+ * - Update database
+ * - Notify share/share.c
+ */
+ share_hash_fn_destroy(fn);
+}
+
+
+static void share_hash_fn_hash(evtp_work_t *w) {
+}
+
+
static void share_hash_fn_opened(evtp_work_t *w) {
share_hash_fn_t *fn = w->data;
- if(fn->cancelled) {
+ if(!fn->fl) {
share_hash_fn_destroy(fn);
return;
}
- /* TODO: the file object should be removed from the tree, both to avoid
- * "memory leaks" caused by scanning temporary files and to ensure that, if
+ /* TODO: the file object should be removed from the tree to ensure that, if
* the file is found again in a subsequent scan, another hash operation is
* attempted. */
if(fn->fd < 0) {
@@ -150,7 +182,10 @@ static void share_hash_fn_opened(evtp_work_t *w) {
fn->openw.data = NULL;
ytrace("File '%s' opened, fd = %d", fn->fn, fn->fd);
- /* TODO: Now schedule the file to be hashed. */
+ fn->chunks = malloc(sizeof(t_res) * fn->chunknum);
+ size_t i;
+ for(i=0; i<fn->jobnum; i++)
+ evtp_submit(&fn->work[i].w, threadpool, share_hash_fn_hash, share_hash_fn_done);
}
@@ -167,7 +202,7 @@ static void share_hash_fn_open(evtp_work_t *w) {
static void share_hash_fn_db(void *data, const char *tth) {
share_hash_fn_t *fn = data;
- if(fn->cancelled) {
+ if(!fn->fl) {
share_hash_fn_destroy(fn);
return;
}