/** * Cleanup the TTH cache by removing needless entries. */ void tth_cache_cleanup(void) { if (0 == atomic_int_inc(&tth_cache_cleanups)) { int id = thread_create(tth_cache_cleanup_thread, NULL, THREAD_F_DETACH | THREAD_F_WARN, THREAD_STACK_MIN); if (-1 == id) atomic_int_dec(&tth_cache_cleanups); } else if (debugging(0)) { g_warning("%s(): concurrent cleanup in progress", G_STRFUNC); atomic_int_dec(&tth_cache_cleanups); } }
/** * Main entry point for the thread that cleans up the TTH cache. */ static void * tth_cache_cleanup_thread(void *unused_arg) { hset_t *shared; const char *rootdir = tth_cache_directory(); pslist_t *dirstack; uint32 flags; ftw_status_t res; (void) unused_arg; if (!is_directory(rootdir)) goto done; /* No TTH cache */ /* * First pass: spot all file entries that are older than our start * time (i.e. were created in another session) and which cannot be * associated with a shared file. */ shared = share_tthset_get(); flags = FTW_O_PHYS | FTW_O_MOUNT | FTW_O_ALL; res = ftw_foreach(rootdir, flags, 0, tth_cache_cleanup_unlink, shared); share_tthset_free(shared); if (res != FTW_STATUS_OK) { g_warning("%s(): initial traversal failed with %d, aborting", G_STRFUNC, res); goto done; } /* * Second pass: spot empty directories and remove them. */ flags |= FTW_O_ENTRY | FTW_O_DEPTH; dirstack = NULL; (void) ftw_foreach(rootdir, flags, 0, tth_cache_cleanup_rmdir, &dirstack); pslist_free(dirstack); /* FALL THROUGH */ done: atomic_int_dec(&tth_cache_cleanups); return NULL; }
int task_free(task_id tid) { task_t f = { tid }; do { lc_spin_lock(lock); task_t *t = map_find(tasks, &f); if (t) { if (atomic_int_dec(&t->ref_count) > 0) break; map_remove(tasks, t); lc_free(t); //printf("Freed task <%f>\n",tid); } } while (0); lc_spin_unlock(lock); return SUCCESS; }