2 Star 1 Fork 0

长江/oscam-nx111

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
oscam-garbage.c 4.48 KB
一键复制 编辑 原始数据 按行查看 历史
gorgone 提交于 2020-10-19 20:32 +08:00 . add unlocks and modify garbage collector
#define MODULE_LOG_PREFIX "gc"
#include "globals.h"
#include "oscam-garbage.h"
#include "oscam-lock.h"
#include "oscam-string.h"
#include "oscam-time.h"
#define HASH_BUCKETS 250
struct cs_garbage
{
time_t time;
void *data;
#ifdef WITH_DEBUG
char *file;
uint32_t line;
#endif
struct cs_garbage *next;
};
static int32_t counter = 0;
static pthread_mutex_t add_lock;
static struct cs_garbage *garbage_first[HASH_BUCKETS];
static CS_MUTEX_LOCK garbage_lock[HASH_BUCKETS];
static pthread_t garbage_thread;
static int32_t garbage_collector_active;
static int32_t garbage_debug;
#ifdef WITH_DEBUG
void add_garbage_debug(void *data, char *file, uint32_t line)
{
#else
void add_garbage(void *data)
{
#endif
if(!data)
{ return; }
if(!garbage_collector_active || garbage_debug == 1)
{
NULLFREE(data);
return;
}
SAFE_MUTEX_LOCK(&add_lock);
int32_t bucket = counter++;
if(counter >= HASH_BUCKETS)
{
counter = 0;
}
SAFE_MUTEX_UNLOCK(&add_lock);
struct cs_garbage *garbage = (struct cs_garbage*)malloc(sizeof(struct cs_garbage));
if(garbage == NULL)
{
cs_log("*** MEMORY FULL -> FREEING DIRECT MAY LEAD TO INSTABILITY!!! ***");
NULLFREE(data);
return;
}
garbage->time = time(NULL);
garbage->data = data;
garbage->next = NULL;
#ifdef WITH_DEBUG
garbage->file = file;
garbage->line = line;
#endif
cs_writelock(__func__, &garbage_lock[bucket]);
#ifdef WITH_DEBUG
if(garbage_debug == 2)
{
struct cs_garbage *garbagecheck = garbage_first[bucket];
while(garbagecheck)
{
if(garbagecheck->data == data)
{
cs_log("Found a try to add garbage twice. Not adding the element to garbage list...");
cs_log("Current garbage addition: %s, line %d.", file, line);
cs_log("Original garbage addition: %s, line %d.", garbagecheck->file, garbagecheck->line);
cs_writeunlock(__func__, &garbage_lock[bucket]);
NULLFREE(garbage);
return;
}
garbagecheck = garbagecheck->next;
}
}
#endif
garbage->next = garbage_first[bucket];
garbage_first[bucket] = garbage;
cs_writeunlock(__func__, &garbage_lock[bucket]);
}
static pthread_cond_t sleep_cond;
static pthread_mutex_t sleep_cond_mutex;
static void garbage_collector(void)
{
int32_t i,j;
struct cs_garbage *garbage, *next, *prev, *first;
set_thread_name(__func__);
int32_t timeout_time = 2 * cfg.ctimeout / 1000 + 6;
while(garbage_collector_active)
{
time_t deltime = time(NULL) - timeout_time;
for(i = 0; i < HASH_BUCKETS; ++i)
{
j = 0;
cs_writelock(__func__, &garbage_lock[i]);
first = garbage_first[i];
for(garbage = first, prev = NULL; garbage; prev = garbage, garbage = garbage->next, j++)
{
if(j == 2)
{
j++;
cs_writeunlock(__func__, &garbage_lock[i]);
}
if(garbage->time < deltime) // all following elements are too new
{
if(prev)
{
prev->next = NULL;
}
else
{
garbage_first[i] = NULL;
}
break;
}
}
cs_writeunlock(__func__, &garbage_lock[i]);
// list has been taken out before so we don't need a lock here anymore!
while(garbage)
{
next = garbage->next;
free(garbage->data);
free(garbage);
garbage = next;
}
}
sleepms_on_cond(__func__, &sleep_cond_mutex, &sleep_cond, 500);
}
pthread_exit(NULL);
}
void start_garbage_collector(int32_t debug)
{
garbage_debug = debug;
int32_t i;
SAFE_MUTEX_INIT(&add_lock, NULL);
for(i = 0; i < HASH_BUCKETS; ++i)
{
cs_lock_create(__func__, &garbage_lock[i], "garbage_lock", 9000);
garbage_first[i] = NULL;
}
cs_pthread_cond_init(__func__, &sleep_cond_mutex, &sleep_cond);
garbage_collector_active = 1;
int32_t ret = start_thread("garbage", (void *)&garbage_collector, NULL, &garbage_thread, 0, 1);
if(ret)
{
cs_exit(1);
}
}
void stop_garbage_collector(void)
{
if(garbage_collector_active)
{
int32_t i;
garbage_collector_active = 0;
SAFE_COND_SIGNAL(&sleep_cond);
cs_sleepms(300);
SAFE_COND_SIGNAL(&sleep_cond);
SAFE_THREAD_JOIN(garbage_thread, NULL);
for(i = 0; i < HASH_BUCKETS; ++i)
{ cs_writelock(__func__, &garbage_lock[i]); }
for(i = 0; i < HASH_BUCKETS; ++i)
{
while(garbage_first[i])
{
struct cs_garbage *next = garbage_first[i]->next;
NULLFREE(garbage_first[i]->data);
NULLFREE(garbage_first[i]);
garbage_first[i] = next;
}
}
for(i = 0; i < HASH_BUCKETS; ++i)
{
cs_writeunlock(__func__, &garbage_lock[i]);
cs_lock_destroy(__func__, &garbage_lock[i]);
}
pthread_mutex_destroy(&add_lock);
pthread_cond_destroy(&sleep_cond);
pthread_mutex_destroy(&sleep_cond_mutex);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/4a02/oscam-nx111.git
git@gitee.com:4a02/oscam-nx111.git
4a02
oscam-nx111
oscam-nx111
master

搜索帮助