UA2F/src/cache.c
SivonZn 1ac208da2e
fix: compilation failed (#135)
* fix: ninja compilation error

* Update src/cache.c

Co-authored-by: Zxilly <31370133+Zxilly@users.noreply.github.com>
Signed-off-by: SivonZn <79399171+SivonZn@users.noreply.github.com>

---------

Signed-off-by: SivonZn <79399171+SivonZn@users.noreply.github.com>
Co-authored-by: Zxilly <31370133+Zxilly@users.noreply.github.com>
2024-09-06 16:23:55 +08:00

98 lines
2.5 KiB
C

#include "cache.h"
#include "third/uthash.h"
#include <pthread.h>
#include <stdbool.h>
#include <sys/syslog.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
pthread_rwlock_t cacheLock;
struct cache *not_http_dst_cache = NULL;
static int check_interval;
_Noreturn static void* check_cache(void* arg __attribute__((unused))) {
while (true) {
pthread_rwlock_wrlock(&cacheLock);
const time_t now = time(NULL);
struct cache *cur, *tmp;
HASH_ITER(hh, not_http_dst_cache, cur, tmp) {
if (difftime(now, cur->last_time) > check_interval * 2) {
HASH_DEL(not_http_dst_cache, cur);
free(cur);
}
}
pthread_rwlock_unlock(&cacheLock);
sleep(check_interval);
}
}
void init_not_http_cache(const int interval) {
check_interval = interval;
if (pthread_rwlock_init(&cacheLock, NULL) != 0) {
syslog(LOG_ERR, "Failed to init cache lock");
exit(EXIT_FAILURE);
}
syslog(LOG_INFO, "Cache lock initialized");
pthread_t cleanup_thread;
const __auto_type ret = pthread_create(&cleanup_thread, NULL, check_cache, NULL);
if (ret) {
syslog(LOG_ERR, "Failed to create cleanup thread: %d", ret);
exit(EXIT_FAILURE);
}
syslog(LOG_INFO, "Cleanup thread created");
pthread_detach(cleanup_thread);
}
bool cache_contains(struct addr_port target) {
pthread_rwlock_rdlock(&cacheLock);
struct cache *s;
HASH_FIND(hh, not_http_dst_cache, &target, sizeof(struct addr_port), s);
pthread_rwlock_unlock(&cacheLock);
if (s != NULL) {
bool ret;
pthread_rwlock_wrlock(&cacheLock);
if (difftime(time(NULL), s->last_time) > check_interval * 2) {
HASH_DEL(not_http_dst_cache, s);
free(s);
ret = false;
} else {
s->last_time = time(NULL);
ret = true;
}
pthread_rwlock_unlock(&cacheLock);
return ret;
}
return false;
}
void cache_add(struct addr_port addr_port) {
pthread_rwlock_wrlock(&cacheLock);
struct cache *s;
HASH_FIND(hh, not_http_dst_cache, &addr_port, sizeof(struct addr_port), s);
if (s == NULL) {
s = malloc(sizeof(struct cache));
memcpy(&s->target.addr, &addr_port, sizeof(struct addr_port));
HASH_ADD(hh, not_http_dst_cache, target.addr, sizeof(struct addr_port), s);
}
s->last_time = time(NULL);
pthread_rwlock_unlock(&cacheLock);
}