void item_scrubber_main(struct default_engine *engine) { hash_item cursor; int ii; memset(&cursor, 0, sizeof(cursor)); cursor.refcount = 1; for (ii = 0; ii < POWER_LARGEST; ++ii) { bool skip = false; cb_mutex_enter(&engine->items.lock); if (engine->items.heads[ii] == NULL) { skip = true; } else { /* add the item at the tail */ do_item_link_cursor(engine, &cursor, ii); } cb_mutex_exit(&engine->items.lock); if (!skip) { item_scrub_class(engine, &cursor); } } cb_mutex_enter(&engine->scrubber.lock); engine->scrubber.stopped = time(NULL); engine->scrubber.running = false; cb_mutex_exit(&engine->scrubber.lock); }
static void *item_scubber_main(void *arg) { struct default_engine *engine = arg; hash_item cursor = { .refcount = 1 }; for (int ii = 0; ii < POWER_LARGEST; ++ii) { pthread_mutex_lock(&engine->cache_lock); bool skip = false; if (engine->items.heads[ii] == NULL) { skip = true; } else { // add the item at the tail do_item_link_cursor(engine, &cursor, ii); } pthread_mutex_unlock(&engine->cache_lock); if (!skip) { item_scrub_class(engine, &cursor); } } pthread_mutex_lock(&engine->scrubber.lock); engine->scrubber.stopped = time(NULL); engine->scrubber.running = false; pthread_mutex_unlock(&engine->scrubber.lock); return NULL; } bool item_start_scrub(struct default_engine *engine) { bool ret = false; pthread_mutex_lock(&engine->scrubber.lock); if (!engine->scrubber.running) { engine->scrubber.started = time(NULL); engine->scrubber.stopped = 0; engine->scrubber.visited = 0; engine->scrubber.cleaned = 0; engine->scrubber.running = true; pthread_t t; pthread_attr_t attr; if (pthread_attr_init(&attr) != 0 || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 || pthread_create(&t, &attr, item_scubber_main, engine) != 0) { engine->scrubber.running = false; } else { ret = true; } } pthread_mutex_unlock(&engine->scrubber.lock); return ret; }