diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/share/hash.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/src/share/hash.c b/src/share/hash.c index 4e24a4d..cc04c92 100644 --- a/src/share/hash.c +++ b/src/share/hash.c @@ -77,6 +77,7 @@ 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; @@ -117,8 +118,26 @@ static void share_hash_fn_destroy(share_hash_fn_t *fn) { } +static void share_hash_fn_cancel(share_hash_fn_t *fn) { + fn->cancelled = true; + if(obj->fns[fn->idx] == fn) + obj->fns[fn->idx] = NULL; + + /* If no hash jobs have been scheduled, then we can immediately remove the + * jobnum count. */ + if(fn->openw.data || fn->fd < 0) { + obj->jobs -= fn->jobnum; + fn->jobnum = 0; + } +} + + static void share_hash_fn_opened(evtp_work_t *w) { share_hash_fn_t *fn = w->data; + if(fn->cancelled) { + 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 @@ -148,6 +167,10 @@ 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) { + share_hash_fn_destroy(fn); + return; + } if(ylog_enabled(YLOG_TRACE)) { char res[49] = {}; @@ -290,11 +313,8 @@ void share_hash_remove(share_t *s, share_fl_t *fl) { size_t i; for(i=0; i<HASH_JOBS; i++) - if(obj->fns[i] && obj->fns[i]->fl == fl) { - /* TODO: Cancel hashing and free fn object */ - obj->fns[i] = NULL; - return; - } + if(obj->fns[i] && obj->fns[i]->fl == fl) + share_hash_fn_cancel(obj->fns[i]); list_remove(s->h, fl); if(!s->h.head) @@ -312,10 +332,8 @@ void share_hash_init(share_t *s) { void share_hash_destroy(share_t *s) { size_t i; for(i=0; i<HASH_JOBS; i++) - if(obj->fns[i] && obj->fns[i]->s == s) { - /* TODO: Cancel hashing and free fn object */ - obj->fns[i] = NULL; - } + if(obj->fns[i] && obj->fns[i]->s == s) + share_hash_fn_cancel(obj->fns[i]); kh_destroy(hashfiles, s->h.hashfiles); } |