示例#1
0
文件: cache.c 项目: cesarghali/PWOSPF
void check_cache(struct cache_item* pFirstItem)
{
    time_t time_stamp;
    time(&time_stamp);
    int current_time_stamp = ((int)(time_stamp));

    struct cache_item* ptr = pFirstItem;

    while(ptr != NULL)
    {
        if (ptr->next_item == NULL)
        {
            break;
        }

        if (current_time_stamp - ptr->next_item->time_stamp >= 15)
        {
            in_addr ip_addr;
            ip_addr.s_addr = ptr->next_item->ip;
            Debug("\n\n**** Removing cache entry, [%s, ", inet_ntoa(ip_addr));
            DebugMAC(ptr->next_item->mac);
            Debug("] *****\n\n");

            remove_cache_item(ptr);

        }

        ptr = ptr->next_item;
    }
}
示例#2
0
static void
cache_cleaner_thread(void *none)
{
    /* Find where it all happens */
    char covers_path[PATH_MAX];
    if (make_cache_root_path(covers_path, PATH_MAX-10)) {
        return;
    }
    strcat(covers_path, "covers");
    const size_t covers_path_length = strlen(covers_path);

    deadbeef->mutex_lock(thread_mutex);
    while (!terminate) {
        time_t oldest_mtime = time(NULL);

        /* Loop through the artist directories */
        DIR *covers_dir = opendir(covers_path);
        struct dirent *covers_subdir;
        while (!terminate && covers_dir && (covers_subdir = readdir(covers_dir))) {
            const int32_t cache_secs = cache_expiry_seconds;
            deadbeef->mutex_unlock(thread_mutex);
            if (cache_secs > 0 && path_ok(covers_path_length, covers_subdir->d_name)) {
                trace("Analyse %s for expired files\n", covers_subdir->d_name);
                const time_t cache_expiry = time(NULL) - cache_secs;

                /* Loop through the image files in this artist directory */
                char subdir_path[PATH_MAX];
                sprintf(subdir_path, "%s/%s", covers_path, covers_subdir->d_name);
                const size_t subdir_path_length = strlen(subdir_path);
                DIR *subdir = opendir(subdir_path);
                struct dirent *entry;
                while (subdir && (entry = readdir(subdir))) {
                    if (path_ok(subdir_path_length, entry->d_name)) {
                        char entry_path[PATH_MAX];
                        sprintf(entry_path, "%s/%s", subdir_path, entry->d_name);

                        /* Test against the cache expiry time (cache invalidation resets are not handled here) */
                        struct stat stat_buf;
                        if (!stat(entry_path, &stat_buf)) {
                            if (stat_buf.st_mtime <= cache_expiry) {
                                trace("%s expired from cache\n", entry_path);
                                remove_cache_item(entry_path, subdir_path, covers_subdir->d_name, entry->d_name);
                            }
                            else if (stat_buf.st_mtime < oldest_mtime) {
                                oldest_mtime = stat_buf.st_mtime;
                            }
                        }
                    }
                }
                if (subdir) {
                    closedir (subdir);
                }
            }
            usleep(100000);
            deadbeef->mutex_lock(thread_mutex);
        }
        if (covers_dir) {
            closedir (covers_dir);
            covers_dir = NULL;
        }

        /* Sleep until just after the oldest file expires */
        if (cache_expiry_seconds > 0 && !terminate) {
            struct timespec wake_time = {
                .tv_sec = time(NULL) + max(60, oldest_mtime - time(NULL) + cache_expiry_seconds),
                .tv_nsec = 999999
            };
            trace("Cache cleaner sleeping for %d seconds\n", max(60, oldest_mtime - time(NULL) + cache_expiry_seconds));
            pthread_cond_timedwait((pthread_cond_t *)thread_cond, (pthread_mutex_t *)thread_mutex, &wake_time);
        }

        /* Just go back to sleep if cache expiry is disabled */
        while (cache_expiry_seconds <= 0 && !terminate) {
            trace("Cache cleaner sleeping forever\n");
            pthread_cond_wait((pthread_cond_t *)thread_cond, (pthread_mutex_t *)thread_mutex);
        }
    }
    deadbeef->mutex_unlock(thread_mutex);
}

void cache_configchanged(void)
{
    const int32_t new_cache_expiry_seconds = deadbeef->conf_get_int("artwork.cache.period", 48) * 60 * 60;
    if (new_cache_expiry_seconds != cache_expiry_seconds) {
        deadbeef->mutex_lock(thread_mutex);
        cache_expiry_seconds = new_cache_expiry_seconds;
        deadbeef->cond_signal(thread_cond);
        deadbeef->mutex_unlock(thread_mutex);
    }
}

void stop_cache_cleaner(void)
{
    if (tid) {
        deadbeef->mutex_lock(thread_mutex);
        terminate = 1;
        deadbeef->cond_signal(thread_cond);
        deadbeef->mutex_unlock(thread_mutex);
        deadbeef->thread_join(tid);
        tid = 0;
        trace("Cache cleaner thread stopped\n");
    }

    if (thread_mutex) {
        deadbeef->mutex_free(thread_mutex);
        thread_mutex = 0;
    }

    if (thread_cond) {
        deadbeef->cond_free(thread_cond);
        thread_cond = 0;
    }

    if (files_mutex) {
        deadbeef->mutex_free(files_mutex);
        files_mutex = 0;
    }
}

int start_cache_cleaner(void)
{
    terminate = 0;
    cache_expiry_seconds = deadbeef->conf_get_int("artwork.cache.period", 48) * 60 * 60;
    files_mutex = deadbeef->mutex_create_nonrecursive();
    thread_mutex = deadbeef->mutex_create_nonrecursive();
    thread_cond = deadbeef->cond_create();
    if (files_mutex && thread_mutex && thread_cond) {
        tid = deadbeef->thread_start_low_priority(cache_cleaner_thread, NULL);
        trace("Cache cleaner thread started\n");
    }

    if (!tid) {
        stop_cache_cleaner();
        return -1;
    }

    return 0;
}