summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/share/hash.c36
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);
}