diff --git a/c/main.c b/c/main.c index 965c572..7cc53a3 100644 --- a/c/main.c +++ b/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 #include #include @@ -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; } \ No newline at end of file diff --git a/c/network/network.c b/c/network/network.c index 0b13a6d..04e037d 100644 --- a/c/network/network.c +++ b/c/network/network.c @@ -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;ipool[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': diff --git a/c/network/network.h b/c/network/network.h index 24498c8..574f958 100644 --- a/c/network/network.h +++ b/c/network/network.h @@ -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 { diff --git a/c/tem/ctl.c b/c/tem/ctl.c index 098f420..9afc1cf 100644 --- a/c/tem/ctl.c +++ b/c/tem/ctl.c @@ -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); } diff --git a/c/tem/ctl.h b/c/tem/ctl.h index ede377a..12547bf 100644 --- a/c/tem/ctl.h +++ b/c/tem/ctl.h @@ -3,6 +3,7 @@ #include #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 \ No newline at end of file diff --git a/c/tools/log/log.c b/c/tools/log/log.c index 7985cbe..4920981 100644 --- a/c/tools/log/log.c +++ b/c/tools/log/log.c @@ -1,8 +1,11 @@ +#define _POSIX_C_SOURCE 200112L #include "log.h" #include #include #include #include +#include +#include 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; } \ No newline at end of file diff --git a/c/tools/log/log.h b/c/tools/log/log.h index 3f66e04..a618b72 100644 --- a/c/tools/log/log.h +++ b/c/tools/log/log.h @@ -2,6 +2,7 @@ #define LOG #include +#include #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 \ No newline at end of file diff --git a/c/tools/quit/quit.c b/c/tools/quit/quit.c index 4abef47..082e346 100644 --- a/c/tools/quit/quit.c +++ b/c/tools/quit/quit.c @@ -1,14 +1,44 @@ #include #include +#include #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) -{ - -} \ No newline at end of file diff --git a/c/tools/quit/quit.h b/c/tools/quit/quit.h index 4618014..12e2dd0 100644 --- a/c/tools/quit/quit.h +++ b/c/tools/quit/quit.h @@ -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 \ No newline at end of file