优化退出流程,统一注册到on_exit(
This commit is contained in:
22
c/main.c
22
c/main.c
@ -1,6 +1,8 @@
|
||||
#define _GNU_SOURCE
|
||||
#include "tem/ctl.h"
|
||||
#include "network/network.h"
|
||||
#include "tools/toml/toml.h"
|
||||
#include "tools/quit/quit.h"
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -45,23 +47,15 @@ int main()
|
||||
pthread_t network_id;
|
||||
pthread_create(&network_id,NULL,networkmanager->run_network,(void*)networkmanager);
|
||||
//启动网络监听与线程池,并加载插件
|
||||
alres *resource = (alres*)malloc(sizeof(alres));
|
||||
resource->loger = logsmanager;
|
||||
resource->network = networkmanager;
|
||||
resource->tem = teml;
|
||||
on_exit(quit_all,resource);
|
||||
//注册清理函数
|
||||
teml->run(teml,fifo);
|
||||
//启动终端
|
||||
pthread_join(network_id,NULL);
|
||||
//等待网络管理器进程结束
|
||||
logs *log = logsmanager->log;
|
||||
while(log != NULL)
|
||||
{
|
||||
logs *buf = log;
|
||||
if(log->next !=NULL)
|
||||
log = log->next;
|
||||
free(buf);
|
||||
}
|
||||
//释放日志内存
|
||||
|
||||
free(teml);
|
||||
free(networkmanager);
|
||||
free(logsmanager);
|
||||
//释放内存
|
||||
return 1;
|
||||
}
|
@ -83,6 +83,7 @@ int init_network(int port)
|
||||
addr.sin_port = htons(port); // 端口号必须网络字节序
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0:本机所有网卡
|
||||
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
listen(fd,10);
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -126,7 +127,7 @@ int iss_work(netm *self,char *command)
|
||||
|
||||
void *pth_module(void *args_p)
|
||||
{
|
||||
args *argms = (args*)args_p;
|
||||
net_args *argms = (net_args*)args_p;
|
||||
pth_m *pmd = argms->pth;
|
||||
log_manager *logger = argms->log;
|
||||
//参数解析
|
||||
@ -172,7 +173,7 @@ int start_pool(netm *self)
|
||||
//为线程开辟管道
|
||||
pipe(self->pool[i].fifo_fd);
|
||||
//启动线程
|
||||
args arg;
|
||||
net_args arg;
|
||||
arg.pth =&self->pool[i];
|
||||
arg.log = self->logmanager;
|
||||
self->pool[i].status = 1;
|
||||
@ -184,8 +185,12 @@ int shutdown_pool(netm *self)
|
||||
{
|
||||
for(int i = 0;i<MAX_POOL;i++)
|
||||
{
|
||||
if(self->pool[i].status == -1)
|
||||
continue;
|
||||
self->pool[i].status = -1;
|
||||
close(self->pool[i].fifo_fd[1]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int server_run(int port,int fifo_fd,netm *self)
|
||||
@ -196,6 +201,7 @@ int server_run(int port,int fifo_fd,netm *self)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
struct epoll_event ev;
|
||||
//设置epoll同时监听控制管道与http请求
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = fifo_fd;
|
||||
epoll_ctl(epfd, EPOLL_CTL_ADD, fifo_fd, &ev);
|
||||
@ -228,7 +234,6 @@ int server_run(int port,int fifo_fd,netm *self)
|
||||
switch(command){
|
||||
case 'q':
|
||||
//退出逻辑
|
||||
server_quit(self);
|
||||
return 1;
|
||||
break;
|
||||
case 'u':
|
||||
|
@ -14,11 +14,11 @@ typedef struct pthread_module
|
||||
atomic_int status;
|
||||
}pth_m;
|
||||
|
||||
typedef struct args
|
||||
typedef struct net_args
|
||||
{
|
||||
log_manager *log;
|
||||
pth_m *pth;
|
||||
}args;
|
||||
}net_args;
|
||||
|
||||
typedef struct network_manager
|
||||
{
|
||||
|
@ -239,6 +239,7 @@ int teml(Ctl *self,int fifo[2])
|
||||
//创建线程用于定期清理日志
|
||||
pthread_create(&self->logwathcher,NULL,self->logmanager->clear_log,self->logmanager);
|
||||
command->statue = 0;
|
||||
self->command = command;
|
||||
do
|
||||
{ //设置缓冲区,接收用户输入
|
||||
write(STDOUT_FILENO,PROMPT,sizeof(PROMPT));
|
||||
@ -252,11 +253,14 @@ int teml(Ctl *self,int fifo[2])
|
||||
const char fexp[256] = {'\0'};
|
||||
memcpy(&input,&fexp,MAX_BUF);
|
||||
}while(command->statue == 0);
|
||||
pthread_kill(self->logwathcher,SIGUSR1);
|
||||
log_manager_stop(self->logmanager);
|
||||
pthread_join(self->logwathcher,NULL);
|
||||
//关闭log定期清理程序
|
||||
close(fifo[0]);
|
||||
|
||||
close(fifo[1]);
|
||||
free_history(self);
|
||||
self->command = NULL;
|
||||
free(command);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include "tools/log/log.h"
|
||||
#include "interpreter/interpreter.h"
|
||||
|
||||
#define MAX_BUF 256
|
||||
#define HISTORY_BUF 256
|
||||
@ -17,8 +18,11 @@ typedef struct Ctl
|
||||
char *history[HISTORY_BUF];
|
||||
pthread_t logwathcher;
|
||||
log_manager *logmanager;
|
||||
ctx *command;//解释器上下文
|
||||
}Ctl;
|
||||
|
||||
Ctl *init_tem(log_manager *logmanager);
|
||||
int free_history(Ctl *self);
|
||||
|
||||
|
||||
#endif
|
@ -1,8 +1,11 @@
|
||||
#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)
|
||||
{
|
||||
@ -11,6 +14,7 @@ int in_log(logs *log,log_manager *self)
|
||||
if(self->log == NULL){
|
||||
self->log = log;
|
||||
self->rear = log;
|
||||
sem_post(&self->log_sem);
|
||||
return 0;
|
||||
}
|
||||
self->count++;
|
||||
@ -25,6 +29,11 @@ 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--;
|
||||
@ -33,27 +42,83 @@ logs *out_log(log_manager *self)
|
||||
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(1000);
|
||||
sleep_with_signal(self);
|
||||
sem_wait(&self->log_sem);
|
||||
if(self->count<256){
|
||||
if((self->count<256||self->log==NULL)&&self->stop !=1){
|
||||
sem_post(&self->log_sem);
|
||||
continue;
|
||||
}
|
||||
logs* buf = self->log;
|
||||
self->log = self->rear =NULL;
|
||||
sem_post(&self->log_sem);
|
||||
logs* tobeclear;
|
||||
while(buf->next !=NULL)
|
||||
{
|
||||
tobeclear = buf;
|
||||
buf = buf->next;
|
||||
free(tobeclear);
|
||||
cleanup(self);
|
||||
if(self->stop == 1){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,8 +131,12 @@ int init_loger(log_manager *self)
|
||||
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;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#define LOG
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MAX_LOG 256
|
||||
|
||||
@ -16,12 +17,17 @@ typedef struct log_manager
|
||||
int (*in_log)(logs *,struct log_manager*);
|
||||
logs* (*out_log)(struct log_manager*);
|
||||
void *(*clear_log)(void*);
|
||||
int (*cleanup)(struct log_manager*);
|
||||
sem_t log_sem;
|
||||
logs *log;
|
||||
logs *rear;
|
||||
int count;
|
||||
pthread_mutex_t mtx;
|
||||
pthread_cond_t cond;
|
||||
int stop;
|
||||
}log_manager;
|
||||
|
||||
void log_manager_stop(log_manager *self);
|
||||
int init_loger(log_manager *self);
|
||||
|
||||
#endif
|
@ -1,14 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quit.h"
|
||||
#include "tem/ctl.h"
|
||||
|
||||
void *quit_all(void *self_p)
|
||||
void quit_all(int status,void *self_p)
|
||||
{
|
||||
alres *resouce =(alres*)self_p;
|
||||
//转换参数
|
||||
|
||||
resouce->network->shutdown_pool(resouce->network);
|
||||
logs *netlog = (logs*)malloc(sizeof(logs));
|
||||
netlog->next = NULL;
|
||||
memcpy(netlog->log,"shuting down networkserver",27);
|
||||
resouce->loger->in_log(netlog,resouce->loger);
|
||||
free(resouce->network);
|
||||
//释放网络资源
|
||||
if(resouce->tem->command !=NULL){
|
||||
free_history(resouce->tem);
|
||||
if(resouce->tem->command->arg != NULL)
|
||||
{
|
||||
args* arg = resouce->tem->command->arg;
|
||||
if(arg->next !=NULL)
|
||||
{
|
||||
while(arg->next != NULL){
|
||||
args* tobefree = arg;
|
||||
arg = arg->next;
|
||||
free(tobefree);
|
||||
}
|
||||
free(arg);
|
||||
}
|
||||
}
|
||||
free(resouce->tem->command);
|
||||
}
|
||||
//释放终端资源
|
||||
pthread_mutex_destroy(&resouce->loger->mtx);
|
||||
resouce->loger->cleanup(resouce->loger);
|
||||
sem_destroy(&resouce->loger->log_sem);
|
||||
//销毁信号量
|
||||
|
||||
free(resouce->loger);
|
||||
//清理日志
|
||||
}
|
||||
|
||||
|
||||
int server_quit(netm *self)
|
||||
{
|
||||
|
||||
}
|
@ -1,9 +1,19 @@
|
||||
#ifndef QUIT
|
||||
#define QUIT
|
||||
#ifndef QUIT_LIB
|
||||
#define QUIT_LIB
|
||||
|
||||
#include "network/network.h"
|
||||
void *quitall(void *self_p);
|
||||
#include "tem/ctl.h"
|
||||
#include "tools/log/log.h"
|
||||
typedef struct all_resources
|
||||
{
|
||||
Ctl *tem;
|
||||
netm *network;
|
||||
log_manager *loger;
|
||||
|
||||
}alres;
|
||||
|
||||
|
||||
void quit_all(int status,void *self_p);
|
||||
|
||||
int server_quit(netm *self);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user