Files
chat_rebot-connect-with-one…/c/tools/log/log.c

142 lines
3.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define _POSIX_C_SOURCE 200112L
#include "log.h"
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
int in_log(logs *log,log_manager *self)
{
sem_wait(&self->log_sem);//加锁
logs *buf = self->rear;
if(self->log == NULL){
self->log = log;
self->rear = log;
sem_post(&self->log_sem);
return 0;
}
self->count++;
buf->next = log;
log->next = NULL;
self->rear = log;
sem_post(&self->log_sem);
return self->count;
}
logs *out_log(log_manager *self)
{
sem_wait(&self->log_sem);
logs *buf = self->log;
if(self->log==NULL)
{
sem_post(&self->log_sem);
return NULL;
}
if(self->log->next ==NULL)
self->log = self->rear = NULL;
self->count--;
sem_post(&self->log_sem);
buf->next =NULL;
return buf;
}
int sleep_with_signal(log_manager *self)
{
struct timespec ts;
int rc;
/* 计算绝对超时:当前 + 1000 s */
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
return -1; /* 罕见失败 */
ts.tv_sec += 1000;
/* 纳秒部分无需处理1000 s 整不会溢出 */
pthread_mutex_lock(&self->mtx); /* 进入临界区 */
while (1) {
rc = pthread_cond_timedwait(&self->cond, &self->mtx, &ts);
if (rc == ETIMEDOUT) { /* 1000 s 到点 */
pthread_mutex_unlock(&self->mtx);
return 1; /* 正常超时 */
}
if (rc != 0) { /* 其他错误 */
pthread_mutex_unlock(&self->mtx);
return -1;
}
/* 被 signal / broadcast 提前唤醒,检查 stop */
if (self->stop == 1) {/* 主线程要求退出 */
pthread_mutex_unlock(&self->mtx);
return 0; /* 告诉调用者:该结束了 */
}
}
}
int cleanup(log_manager *self)
{
if(self->log ==NULL)
return 1;
logs *tobeclean,*loc;
sem_wait(&self->log_sem);
loc = self->log;
self->log = NULL;
sem_post(&self->log_sem);
while(loc->next !=NULL)
{
tobeclean = loc;
loc = loc->next;
free(tobeclean);
}
free(loc);
}
void log_manager_stop(log_manager *self)
{
pthread_mutex_lock(&self->mtx);
self->stop = 1; /* 置退出标志 */
pthread_cond_broadcast(&self->cond); /* 唤醒所有等待线程 */
printf("stopping loger\n");
pthread_mutex_unlock(&self->mtx);
printf("done\n");
}
//定期清理函数
void *clear_log(void *self_p)
{
log_manager *self = (log_manager*)self_p;
for(;;)
{
sleep_with_signal(self);
sem_wait(&self->log_sem);
if((self->count<256||self->log==NULL)&&self->stop !=1){
sem_post(&self->log_sem);
continue;
}
sem_post(&self->log_sem);
cleanup(self);
if(self->stop == 1){
return NULL;
}
}
}
int init_loger(log_manager *self)
{
if(self == NULL)
{
perror("NULL\n");
return -1;
}
sem_init(&self->log_sem, 0,1);
pthread_mutex_init(&self->mtx,NULL);
pthread_cond_init(&self->cond,NULL);
self->in_log = in_log;
self->out_log = out_log;
self->clear_log = clear_log;
self->log = NULL;
self->stop = 0;
self->cleanup = cleanup;
}