int swReactorPoll_create(swReactor *reactor, int max_fd_num) { //create reactor object swReactorPoll *object = sw_malloc(sizeof(swReactorPoll)); if (object == NULL) { swError("malloc[0] failed"); return SW_ERR; } bzero(object, sizeof(swReactorPoll)); object->fds = sw_calloc(max_fd_num, sizeof(swPollFdInfo)); if (object->fds == NULL) { swError("malloc[1] failed"); return SW_ERR; } object->events = sw_calloc(max_fd_num, sizeof(struct pollfd)); if (object->events == NULL) { swError("malloc[2] failed"); return SW_ERR; } object->max_fd_num = max_fd_num; bzero(reactor->handle, sizeof(reactor->handle)); reactor->object = object; //binding method reactor->add = swReactorPoll_add; reactor->del = swReactorPoll_del; reactor->set = swReactorPoll_set; reactor->wait = swReactorPoll_wait; reactor->free = swReactorPoll_free; reactor->setHandle = swReactor_setHandle; return SW_OK; }
/** * worker main loop */ int swWorker_loop(swFactory *factory, int worker_id) { swServer *serv = factory->ptr; #ifndef SW_WORKER_USE_SIGNALFD SwooleG.use_signalfd = 0; #endif //worker_id SwooleWG.id = worker_id; SwooleWG.request_count = 0; SwooleG.pid = getpid(); //signal init swWorker_signal_init(); swWorker *worker = swServer_get_worker(serv, worker_id); swServer_worker_init(serv, worker); SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } serv->workers[worker_id].status = SW_WORKER_IDLE; int pipe_worker = serv->workers[worker_id].pipe_worker; swSetNonBlock(pipe_worker); SwooleG.main_reactor->ptr = serv; //这里的add函数是epoll的add函数 SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite); swWorker_onStart(serv); #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif //main loop SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); //clear pipe buffer swWorker_clean(); //worker shutdown swWorker_onStop(serv); return SW_OK; }
void swoole_init(void) { struct rlimit rlmt; if (SwooleG.running == 0) { bzero(&SwooleG, sizeof(SwooleG)); bzero(sw_error, SW_ERROR_MSG_SIZE); //初始化全局变量 SwooleG.running = 1; sw_errno = 0; SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN); SwooleG.pagesize = getpagesize(); if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0) { swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno); } else { SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur; } //random seed srandom(time(NULL)); //init global lock swMutex_create(&SwooleG.lock, 0); //init signalfd #ifdef HAVE_SIGNALFD swSignalfd_init(); SwooleG.use_signalfd = 1; #endif //timerfd #ifdef HAVE_TIMERFD SwooleG.use_timerfd = 1; #endif SwooleG.use_timer_pipe = 1; //将日志设置为标准输出 SwooleG.log_fd = STDOUT_FILENO; //初始化全局内存 SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1); if (SwooleG.memory_pool == NULL) { swError("[Master] Fatal Error: create global memory fail. Error: %s[%d]", strerror(errno), errno); } SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS)); if (SwooleGS == NULL) { swError("[Master] Fatal Error: alloc memory for SwooleGS fail. Error: %s[%d]", strerror(errno), errno); } } }
static int swFactoryProcess_writer_start(swFactory *factory) { swFactoryProcess *this = factory->object; swThreadParam *param; int i; pthread_t pidt; swThreadStartFunc thread_main; #ifdef SW_USE_SHM_CHAN thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_ex; #else thread_main = (swThreadStartFunc)swFactoryProcess_writer_loop; #endif for (i = 0; i < this->writer_num; i++) { param = sw_malloc(sizeof(swThreadParam)); if (param == NULL ) { swError("malloc fail\n"); return SW_ERR; } #ifdef SW_USE_SHM_CHAN #if defined(SW_CHAN_USE_MMAP) || SW_CHAN_USE_MMAP==1 mm = swShareMemory_mmap_create(&this->writers[i].shm, SW_CHAN_BUFFER_SIZE, 0); #else mm = swShareMemory_sysv_create(&this->writers[i].shm, SW_CHAN_BUFFER_SIZE, SW_CHAN_SYSV_KEY); #endif if (mm == NULL ) { swError("shm_create fail\n"); return SW_ERR; } if (swChan_create(&this->writers[i].chan, mm, SW_CHAN_BUFFER_SIZE, SW_CHAN_ELEM_SIZE) < 0) { swError("swChan_create fail\n"); return SW_ERR; } #endif param->object = factory; param->pti = i; if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0) { swTrace("pthread_create fail\n"); return SW_ERR; } this->writers[i].ptid = pidt; SW_START_SLEEP; } return SW_OK; }
static int swFactoryProcess_writer_start(swFactory *factory) { swFactoryProcess *object = factory->object; swThreadParam *param; int i; pthread_t pidt; swThreadStartFunc thread_main; #if SW_WORKER_IPC_MODE == 2 thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_queue; #else thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_unsock; #endif for (i = 0; i < object->writer_num; i++) { param = sw_malloc(sizeof(swPipe)); if (param == NULL) { swError("malloc fail\n"); return SW_ERR; } param->object = factory; param->pti = i; if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0) { swTrace("pthread_create fail\n"); return SW_ERR; } pthread_detach(pidt); object->writers[i].ptid = pidt; SW_START_SLEEP; } return SW_OK; }
static int swReactorPoll_add(swReactor *reactor, int fd, int fdtype) { swReactorPoll *object = reactor->object; int cur = reactor->event_num; if (reactor->event_num == object->max_fd_num) { swError("too many connection, more than %d", object->max_fd_num); return SW_ERR; } object->fds[cur].fdtype = swReactor_fdtype(fdtype); object->events[cur].fd = fd; //object->events[cur].events = POLLRDHUP; object->events[cur].events = 0; if (swReactor_event_read(fdtype)) { object->events[cur].events |= POLLIN; } if (swReactor_event_write(fdtype)) { object->events[cur].events |= POLLOUT; } if (swReactor_event_error(fdtype)) { object->events[cur].events |= POLLHUP; } reactor->event_num++; return SW_OK; }
static int swFactoryProcess_writer_start(swFactory *factory) { swServer *serv = SwooleG.serv; swThreadParam *param; int i; pthread_t pidt; swThreadStartFunc thread_main; if (serv->ipc_mode == SW_IPC_MSGQUEUE) { thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_queue; } else { #if SW_USE_WRITER_THREAD thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_unsock; #else swError("never get here"); #endif } for (i = 0; i < serv->writer_num; i++) { param = sw_malloc(sizeof(swPipe)); if (param == NULL) { swError("malloc fail\n"); return SW_ERR; } param->object = factory; param->pti = i; if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0) { swTrace("pthread_create fail\n"); return SW_ERR; } pthread_detach(pidt); serv->writer_threads[i].ptid = pidt; SW_START_SLEEP; } return SW_OK; }
void swSignalfd_init() { sigemptyset(&swoole_signalfd_mask); object.items = sw_calloc(SW_SIGNAL_INIT_NUM, sizeof(swSignal_item)); if (object.items == NULL) { swError("malloc for swSignal_item failed."); } object.size = SW_SIGNAL_INIT_NUM; object.num = 0; }
/** * 主进程向worker进程发送数据 * @param worker_id 发到指定的worker进程 */ int swFactoryProcess_send2worker(swFactory *factory, swEventData *data, int worker_id) { swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; int pti; int ret; int send_len = sizeof(data->info) + data->info.len; if (worker_id < 0) { //轮询 // data->info.from_id > serv->poll_thread_num, UDP必须使用轮询 if (serv->dispatch_mode == SW_DISPATCH_ROUND || data->info.from_id > serv->poll_thread_num) { pti = (object->worker_pti++) % object->worker_num; } //使用fd取摸来散列 else if (serv->dispatch_mode == SW_DISPATCH_FDMOD) { pti = data->info.fd % object->worker_num; } //使用抢占式队列(IPC消息队列)分配 else { #if SW_WORKER_IPC_MODE != 2 swError("SW_DISPATCH_QUEUE must use (SW_WORKER_IPC_MODE = 2)"); #endif //msgsnd参数必须>0 //worker进程中正确的mtype应该是pti + 1 pti = object->worker_num; } } //指定了worker_id else { pti = worker_id; } #if SW_WORKER_IPC_MODE == 2 //insert to msg queue swQueue_data *in_data = (swQueue_data *)((void *)data - sizeof(long)); //加1防止id为0的worker进程出错 in_data->mtype = pti + 1; swDataHead *info = (swDataHead *)in_data->mdata; ret = object->rd_queue.in(&object->rd_queue, in_data, send_len); swTrace("[Master]rd_queue[%ld]->in: fd=%d|type=%d|len=%d", in_data->mtype, info->fd, info->type, info->len); #else //send to unix sock ret = swWrite(object->workers[pti].pipe_master, (char *) data, send_len); #endif return ret; }
void swoole_init(void) { if (SwooleG.running == 0) { bzero(&SwooleG, sizeof(SwooleG)); bzero(sw_error, SW_ERROR_MSG_SIZE); //初始化全局变量 SwooleG.running = 1; sw_errno = 0; //init global lock swMutex_create(&SwooleG.lock, 0); //init signalfd #ifdef HAVE_SIGNALFD swSignalfd_init(); SwooleG.use_signalfd = 1; #endif //timerfd #ifdef HAVE_TIMERFD SwooleG.use_timerfd = 1; #endif //将日志设置为标准输出 SwooleG.log_fd = STDOUT_FILENO; //初始化全局内存 SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1); if(SwooleG.memory_pool == NULL) { swError("[Master] Fatal Error: create global memory fail. Error: %s[%d]", strerror(errno), errno); } SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS)); if(SwooleGS == NULL) { swError("[Master] Fatal Error: alloc memory for SwooleGS fail. Error: %s[%d]", strerror(errno), errno); } } }
int swRingQueue_init(swRingQueue * p_queue, int buffer_size) { p_queue->data = sw_calloc(buffer_size, sizeof(void*)); if(p_queue->data == NULL) { swError("malloc fail\n"); return -1; } p_queue->size = buffer_size; p_queue->head = 0; p_queue->tail = 0; p_queue->tag = 0; return 0; }
void swSignalfd_add(int signo, __sighandler_t callback) { if (object.num == object.size) { object.items = sw_realloc(object.items, sizeof(swSignal_item) * object.size * 2); if (object.items == NULL) { swError("realloc for swSignal_item failed."); return; } object.size = object.size * 2; } sigaddset(&swoole_signalfd_mask, signo); object.items[object.num].callback = callback; object.items[object.num].signo = signo; object.num ++; }
int swFactoryProcess_controller_start(swFactory *factory) { int i, pid; swController *controller; //循环fork LL_FOREACH(manager_controller_list, controller) { controller->pipe_fd = manager_controller_pipes[controller->id].pipes[1]; pid = swFactoryProcess_controller_spawn(factory, controller); if(pid < 0) { swError("Fork controller process fail.Errno=%d", errno); return SW_ERR; } else { controller->pid = pid; } }
int swSocket_create(int type) { int _domain; int _type; switch (type) { case SW_SOCK_TCP: _domain = PF_INET; _type = SOCK_STREAM; break; case SW_SOCK_TCP6: _domain = PF_INET6; _type = SOCK_STREAM; break; case SW_SOCK_UDP: _domain = PF_INET; _type = SOCK_DGRAM; break; case SW_SOCK_UDP6: _domain = PF_INET6; _type = SOCK_DGRAM; break; case SW_SOCK_UNIX_DGRAM: _domain = PF_UNIX; _type = SOCK_DGRAM; break; case SW_SOCK_UNIX_STREAM: _domain = PF_UNIX; _type = SOCK_STREAM; break; default: swError("unknow socket type [%d]", type); return SW_ERR; } return socket(_domain, _type, 0); }
static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti) { struct { long pti; swEventData req; } rdata; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; int pipe_rd = object->workers[worker_pti].pipe_worker; int n; c_worker_pti = worker_pti; object->manager_pid = getppid(); #if SW_WORKER_IPC_MODE == 2 //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_pti + 1; } #else SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if(SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor fail"); return SW_ERR; } if(swReactor_auto(SwooleG.main_reactor, serv->max_conn) < 0) { swError("[Worker] create worker_reactor fail"); return SW_ERR; } SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive); #endif if(factory->max_request < 1) { worker_task_always = 1; } else { worker_task_num = factory->max_request; worker_task_num += get_rand(worker_pti); } #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set fail\n"); } } #endif if (serv->onWorkerStart != NULL) { //worker进程启动时调用 serv->onWorkerStart(serv, worker_pti); } struct timeval timeo; timeo.tv_sec = SW_REACTOR_TIMEO_SEC; timeo.tv_usec = SW_REACTOR_TIMEO_USEC; #if SW_WORKER_IPC_MODE == 2 //主线程 while (swoole_running > 0) { n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req)); if (n < 0) { swWarn("[Worker]rd_queue[%ld]->out wait. Error: %s [%d]", rdata.pti, strerror(errno), errno); continue; } swFactoryProcess_worker_excute(factory, &rdata.req); } #else SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo); #endif if (serv->onWorkerStop != NULL) { //worker进程结束时调用 serv->onWorkerStop(serv, worker_pti); } swTrace("[Worker]max request\n"); return SW_OK; }
//create worker child proccess static int swFactoryProcess_manager_start(swFactory *factory) { swFactoryProcess *object = factory->object; int i, pid, ret; int writer_pti; swServer *serv = factory->ptr; #if SW_WORKER_IPC_MODE == 2 #define _SW_PATH_BUF_LEN 128 //这里使用ftok来获取消息队列的key char path_buf[_SW_PATH_BUF_LEN]; char *path_ptr = getcwd(path_buf, _SW_PATH_BUF_LEN); //读数据队列 if(swQueueMsg_create(&object->rd_queue, 1, ftok(path_ptr, 1), 1) < 0) { swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //为TCP创建写队列 if (serv->have_tcp_sock == 1) { //写数据队列 if(swQueueMsg_create(&object->wt_queue, 1, ftok(path_ptr, 2), 1) < 0) { swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } } #else object->pipes = sw_calloc(object->worker_num, sizeof(swPipe)); if (object->pipes == NULL) { swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //worker进程的pipes for (i = 0; i < object->worker_num; i++) { if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0) { swError("create unix socket[1] fail"); return SW_ERR; } object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1); object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0); } #endif if (serv->task_worker_num > 0) { if (swProcessPool_create(&SwooleG.task_workers, serv->task_worker_num, serv->max_request)< 0) { swWarn("[Master] create task_workers fail"); return SW_ERR; } //设置指针和回调函数 SwooleG.task_workers.ptr = serv; SwooleG.task_workers.onTask = swTaskWorker_onTask; } pid = fork(); switch (pid) { //创建manager进程 case 0: for (i = 0; i < object->worker_num; i++) { // close(worker_pipes[i].pipes[0]); writer_pti = (i % object->writer_num); object->workers[i].writer_id = writer_pti; pid = swFactoryProcess_worker_spawn(factory, i); if (pid < 0) { swError("Fork worker process fail"); return SW_ERR; } else { object->workers[i].pid = pid; } } //创建task_worker进程 if (serv->task_worker_num > 0) { swProcessPool_start(&SwooleG.task_workers); } //标识为管理进程 SwooleG.process_type = SW_PROCESS_MANAGER; ret = swFactoryProcess_manager_loop(factory); exit(ret); break; //主进程 default: object->manager_pid = pid; //TCP需要writer线程 if (serv->have_tcp_sock == 1) { int ret = swFactoryProcess_writer_start(factory); if (ret < 0) { return SW_ERR; } } #if SW_WORKER_IPC_MODE != 2 for (i = 0; i < object->worker_num; i++) { writer_pti = (i % object->writer_num); object->workers[i].writer_id = writer_pti; if (serv->have_tcp_sock == 1) { //将写pipe设置到writer的reactor中 object->writers[writer_pti].reactor.add(&(object->writers[writer_pti].reactor), object->workers[i].pipe_master, SW_FD_PIPE); } } #endif break; case -1: swError("[swFactoryProcess_worker_start]fork manager process fail\n"); return SW_ERR; } return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i, writer_pti; int reload_worker_i = 0; int ret; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; swWorker *reload_workers; reload_workers = sw_calloc(object->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } //for reload swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0); while (swoole_running > 0) { pid = wait(NULL); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("[Manager] wait fail. Error: %s [%d]", strerror(errno), errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, object->workers, sizeof(swWorker) * object->worker_num); manager_reload_flag = 1; goto kill_worker; } } if (swoole_running == 1) { for (i = 0; i < object->worker_num; i++) { //对比pid if (pid != object->workers[i].pid) { continue; } else { pid = 0; new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { swWarn("Fork worker process fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } else { object->workers[i].pid = new_pid; } } } //task worker if(pid > 0) { swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(&SwooleG.task_workers, exit_worker); } } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= object->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("[Manager]kill fail.pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno); continue; } reload_worker_i++; } } sw_free(reload_workers); return SW_OK; }
void swoole_init(void) { struct rlimit rlmt; if (SwooleG.running) { return; } bzero(&SwooleG, sizeof(SwooleG)); bzero(&SwooleWG, sizeof(SwooleWG)); bzero(sw_error, SW_ERROR_MSG_SIZE); SwooleG.running = 1; sw_errno = 0; SwooleG.log_fd = STDOUT_FILENO; SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN); SwooleG.pagesize = getpagesize(); SwooleG.pid = getpid(); SwooleG.socket_buffer_size = SW_SOCKET_BUFFER_SIZE; //get system uname uname(&SwooleG.uname); //random seed srandom(time(NULL)); //init global shared memory SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1); if (SwooleG.memory_pool == NULL) { printf("[Master] Fatal Error: create global memory failed."); exit(1); } SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS)); if (SwooleGS == NULL) { printf("[Master] Fatal Error: alloc memory for SwooleGS failed."); exit(2); } //init global lock swMutex_create(&SwooleGS->lock, 1); swMutex_create(&SwooleGS->lock_2, 1); if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0) { swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno); SwooleG.max_sockets = 1024; } else { SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur; } SwooleG.module_stack = swString_new(8192); if (SwooleG.module_stack == NULL) { exit(3); } if (!SwooleG.task_tmpdir) { SwooleG.task_tmpdir = strndup(SW_TASK_TMP_FILE, sizeof(SW_TASK_TMP_FILE)); SwooleG.task_tmpdir_len = sizeof(SW_TASK_TMP_FILE); } char *tmp_dir = swoole_dirname(SwooleG.task_tmpdir); //create tmp dir if (access(tmp_dir, R_OK) < 0 && swoole_mkdir_recursive(tmp_dir) < 0) { swWarn("create task tmp dir(%s) failed.", tmp_dir); } if (tmp_dir) { sw_strdup_free(tmp_dir); } //init signalfd #ifdef HAVE_SIGNALFD swSignalfd_init(); SwooleG.use_signalfd = 1; #endif //timerfd #ifdef HAVE_TIMERFD SwooleG.use_timerfd = 1; #endif SwooleG.use_timer_pipe = 1; SwooleStats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats)); if (SwooleStats == NULL) { swError("[Master] Fatal Error: alloc memory for SwooleStats failed."); } swoole_update_time(); }
/** * worker main loop */ int swWorker_loop(swFactory *factory, int worker_id) { swServer *serv = factory->ptr; #ifndef SW_WORKER_USE_SIGNALFD SwooleG.use_signalfd = 0; #elif defined(HAVE_SIGNALFD) SwooleG.use_signalfd = 1; #endif //timerfd #ifdef HAVE_TIMERFD SwooleG.use_timerfd = 1; #endif //worker_id SwooleWG.id = worker_id; SwooleWG.request_count = 0; SwooleG.pid = getpid(); //signal init swWorker_signal_init(); swWorker *worker = swServer_get_worker(serv, worker_id); swServer_worker_init(serv, worker); SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } serv->workers[worker_id].status = SW_WORKER_IDLE; int pipe_worker = serv->workers[worker_id].pipe_worker; swSetNonBlock(pipe_worker); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite); /** * set pipe buffer size */ int i; swConnection *pipe_socket; for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++) { worker = swServer_get_worker(serv, i); pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_master); pipe_socket->buffer_size = serv->pipe_buffer_size; pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_worker); pipe_socket->buffer_size = serv->pipe_buffer_size; } swWorker_onStart(serv); #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif //main loop SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); //clear pipe buffer swWorker_clean(); //worker shutdown swWorker_onStop(serv); return SW_OK; }
/** * worker main loop */ static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti) { swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; struct { long pti; swEventData req; } rdata; int n; int pipe_rd = object->workers[worker_pti].pipe_worker; #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set failed"); } } #endif //signal init swFactoryProcess_worker_signal_init(); //worker_id SwooleWG.id = worker_pti; #ifndef SW_USE_RINGBUFFER int i; //for open_check_eof and open_check_length if (serv->open_eof_check || serv->open_length_check) { SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num); if (SwooleWG.buffer_input == NULL) { swError("malloc for SwooleWG.buffer_input failed."); return SW_ERR; } for (i = 0; i < serv->reactor_num; i++) { SwooleWG.buffer_input[i] = swString_new(serv->buffer_input_size); if (SwooleWG.buffer_input[i] == NULL) { swError("buffer_input init failed."); return SW_ERR; } } } #endif if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_pti + 1; } } else { SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } swSetNonBlock(pipe_rd); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive); #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif } if (factory->max_request < 1) { worker_task_always = 1; } else { worker_task_num = factory->max_request; worker_task_num += swRandom(worker_pti); } //worker start if (serv->onWorkerStart != NULL) { serv->onWorkerStart(serv, worker_pti); } if (serv->ipc_mode == SW_IPC_MSGQUEUE) { while (SwooleG.running > 0) { n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req)); if (n < 0) { if (errno == EINTR) { if (SwooleG.signal_alarm && serv->onTimer) { swTimer_select(&SwooleG.timer); SwooleG.signal_alarm = 0; } } else { swWarn("[Worker]rd_queue[%ld]->out wait failed. Error: %s [%d]", rdata.pti, strerror(errno), errno); } continue; } swFactoryProcess_worker_excute(factory, &rdata.req); } } else { struct timeval timeo; timeo.tv_sec = SW_REACTOR_TIMEO_SEC; timeo.tv_usec = SW_REACTOR_TIMEO_USEC; SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo); } if (serv->onWorkerStop != NULL) { //worker shutdown serv->onWorkerStop(serv, worker_pti); } swTrace("[Worker]max request"); return SW_OK; }
int swTimer_start(swTimer *timer, int interval_ms) { struct timeval now; if (gettimeofday(&now, NULL) < 0) { swWarn("malloc fail\n"); return SW_ERR; } timer->interval_ms = interval_ms; timer->lasttime = interval_ms; int sec = interval_ms / 1000; int msec = (((float) interval_ms / 1000) - sec) * 1000; #ifdef HAVE_TIMERFD struct itimerspec timer_set; memset(&timer_set, 0, sizeof(timer_set)); timer->fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC); if (timer->fd < 0) { swError("create timerfd fail\n"); return SW_ERR; } timer_set.it_value.tv_sec = now.tv_sec + sec; timer_set.it_value.tv_nsec = now.tv_usec + msec * 1000; timer_set.it_interval.tv_sec = sec; timer_set.it_interval.tv_nsec = msec * 1000 * 1000; if (timerfd_settime(timer->fd, TFD_TIMER_ABSTIME, &timer_set, NULL) == -1) { swWarn("set timer fail\n"); return SW_ERR; } timer->use_pipe = 0; #else struct itimerval timer_set; int ret; //eventfd是2.6.26提供的,timerfd是2.6.27提供的 #ifdef HAVE_EVENTFD ret = swPipeEventfd_create(&timer->pipe, 0, 0); #else ret = swPipeBase_create(&timer->pipe, 0); #endif if (ret < 0) { swWarn("create timer pipe fail"); return SW_ERR; } memset(&timer_set, 0, sizeof(timer_set)); timer_set.it_value.tv_sec = sec; timer_set.it_value.tv_usec = msec * 1000; timer_set.it_interval.tv_sec = sec; timer_set.it_interval.tv_usec = msec * 1000; if (setitimer(ITIMER_REAL, &timer_set, NULL) < 0) { swWarn("set timer fail"); return SW_ERR; } timer->fd = timer->pipe.getFd(&timer->pipe, 0); timer->use_pipe = 1; #endif return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i; int reload_worker_i = 0; int ret; int worker_exit_code; SwooleG.use_signalfd = 0; SwooleG.use_timerfd = 0; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; swWorker *reload_workers; if (serv->onManagerStart) { serv->onManagerStart(serv); } reload_workers = sw_calloc(serv->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] failed"); return SW_ERR; } //for reload swSignal_add(SIGUSR1, swManagerSignalHanlde); while (SwooleG.running > 0) { pid = wait(&worker_exit_code); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, object->workers, sizeof(swWorker) * serv->worker_num); manager_reload_flag = 1; goto kill_worker; } } if (SwooleG.running == 1) { for (i = 0; i < serv->worker_num; i++) { //对比pid if (pid != object->workers[i].pid) { continue; } else { if(serv->onWorkerError!=NULL && WEXITSTATUS(worker_exit_code) > 0) { serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code)); } pid = 0; new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } else { object->workers[i].pid = new_pid; } } } //task worker if(pid > 0) { swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(exit_worker); } } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= serv->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("[Manager]kill failed, pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno); continue; } reload_worker_i++; } } sw_free(reload_workers); if (serv->onManagerStop) { serv->onManagerStop(serv); } return SW_OK; }
void swoole_init(void) { struct rlimit rlmt; if (SwooleG.running) { return; } bzero(&SwooleG, sizeof(SwooleG)); bzero(&SwooleWG, sizeof(SwooleWG)); bzero(sw_error, SW_ERROR_MSG_SIZE); SwooleG.running = 1; sw_errno = 0; SwooleG.log_fd = STDOUT_FILENO; SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN); SwooleG.pagesize = getpagesize(); SwooleG.pid = getpid(); //get system uname uname(&SwooleG.uname); //random seed srandom(time(NULL)); //init global shared memory SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1); if (SwooleG.memory_pool == NULL) { printf("[Master] Fatal Error: create global memory failed."); exit(1); } SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS)); if (SwooleGS == NULL) { printf("[Master] Fatal Error: alloc memory for SwooleGS failed."); exit(2); } //init global lock swMutex_create(&SwooleGS->lock, 1); swMutex_create(&SwooleGS->lock_2, 1); if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0) { swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno); SwooleG.max_sockets = 1024; } else { SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur; } //init signalfd #ifdef HAVE_SIGNALFD swSignalfd_init(); SwooleG.use_signalfd = 1; #endif //timerfd #ifdef HAVE_TIMERFD SwooleG.use_timerfd = 1; #endif SwooleG.use_timer_pipe = 1; SwooleStats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats)); if (SwooleStats == NULL) { swError("[Master] Fatal Error: alloc memory for SwooleStats failed."); } swoole_update_time(); }
/** * worker main loop */ int swWorker_loop(swFactory *factory, int worker_id) { swServer *serv = factory->ptr; #ifndef SW_WORKER_USE_SIGNALFD SwooleG.use_signalfd = 0; #endif //worker_id SwooleWG.id = worker_id; SwooleG.pid = getpid(); //signal init swWorker_signal_init(); swWorker *worker = swServer_get_worker(serv, worker_id); swServer_worker_init(serv, worker); SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } int pipe_worker = serv->workers[worker_id].pipe_worker; swSetNonBlock(pipe_worker); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite); if (serv->max_request < 1) { SwooleWG.run_always = 1; } else { worker_task_num = serv->max_request; if (worker_task_num > 10) { worker_task_num += swRandom(worker_id); } } swWorker_onStart(serv); #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); swWorker_onStop(serv); return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i, writer_pti; int reload_worker_i = 0; int ret; swFactoryProcess *this = factory->object; swWorkerChild *reload_workers; reload_workers = sw_calloc(this->worker_num, sizeof(swWorkerChild)); if (reload_workers == NULL ) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } //for reload swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0); while (1) { pid = wait(NULL ); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("wait fail.errno=%d\n", errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, this->workers, sizeof(swWorkerChild) * this->worker_num); manager_reload_flag = 1; goto kill_worker; } } for (i = 0; i < this->worker_num; i++) { if (pid != this->workers[i].pid) continue; writer_pti = (i % this->writer_num); new_pid = swFactoryProcess_worker_spawn(factory, writer_pti, i); if (new_pid < 0) { swWarn("Fork worker process fail.Errno=%d\n", errno); return SW_ERR; } else { this->workers[i].pid = new_pid; } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= this->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("kill fail.pid=%d|errno=%d\n", reload_workers[reload_worker_i].pid, errno); continue; } reload_worker_i++; } } return SW_OK; }
int swProcessPool_wait(swProcessPool *pool) { int pid, new_pid; int reload_worker_i = 0; int ret, i; swWorker *reload_workers; reload_workers = sw_calloc(pool->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } while (1) { pid = wait(NULL); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (pool->reloading == 0) { swTrace("[Manager] wait fail. Error: %s [%d]", strerror(errno), errno); } else if (pool->reload_flag == 0) { memcpy(reload_workers, pool->workers, sizeof(swWorker) * pool->worker_num); pool->reload_flag = 1; goto reload_worker; } } if (SwooleG.running == 1) { swWorker *exit_worker = swHashMap_find_int(&pool->map, pid); if (exit_worker == NULL) { swWarn("[Manager]unknow worker[pid=%d]", pid); continue; } new_pid = swProcessPool_spawn(exit_worker); if (new_pid < 0) { swWarn("Fork worker process fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } swHashMap_del_int(&pool->map, pid); } //reload worker reload_worker: if (pool->reloading == 1) { //reload finish if (reload_worker_i >= pool->worker_num) { pool->reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("[Manager]kill fail.pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno); continue; } reload_worker_i++; } } return SW_OK; }
//create worker child proccess static int swFactoryProcess_manager_start(swFactory *factory) { swFactoryProcess *object = factory->object; int i, pid, ret; int reactor_pti; swServer *serv = factory->ptr; if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //读数据队列 if (swQueueMsg_create(&object->rd_queue, 1, serv->message_queue_key, 1) < 0) { swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //为TCP创建写队列 if (serv->have_tcp_sock == 1) { //写数据队列 if (swQueueMsg_create(&object->wt_queue, 1, serv->message_queue_key + 1, 1) < 0) { swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } } } else { object->pipes = sw_calloc(serv->worker_num, sizeof(swPipe)); if (object->pipes == NULL) { swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //worker进程的pipes for (i = 0; i < serv->worker_num; i++) { if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0) { swError("create unix socket[1] fail"); return SW_ERR; } object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1); object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0); } } if (SwooleG.task_worker_num > 0) { key_t msgqueue_key = 0; if (SwooleG.task_ipc_mode > 0) { msgqueue_key = serv->message_queue_key + 2; } if (swProcessPool_create(&SwooleG.task_workers, SwooleG.task_worker_num, serv->max_request, msgqueue_key)< 0) { swWarn("[Master] create task_workers fail"); return SW_ERR; } //设置指针和回调函数 SwooleG.task_workers.ptr = serv; SwooleG.task_workers.onTask = swTaskWorker_onTask; if (serv->onWorkerStart != NULL) { SwooleG.task_workers.onWorkerStart = swTaskWorker_onWorkerStart; } } pid = fork(); switch (pid) { //创建manager进程 case 0: //创建子进程 for (i = 0; i < serv->worker_num; i++) { //close(worker_pipes[i].pipes[0]); reactor_pti = (i % serv->writer_num); object->workers[i].reactor_id = reactor_pti; pid = swFactoryProcess_worker_spawn(factory, i); if (pid < 0) { swError("Fork worker process fail"); return SW_ERR; } else { object->workers[i].pid = pid; } } /** * create task worker pool */ if (SwooleG.task_worker_num > 0) { swProcessPool_start(&SwooleG.task_workers); } //标识为管理进程 SwooleG.process_type = SW_PROCESS_MANAGER; ret = swFactoryProcess_manager_loop(factory); exit(ret); break; //主进程 default: SwooleGS->manager_pid = pid; break; case -1: swError("[swFactoryProcess_worker_start]fork manager process fail"); return SW_ERR; } return SW_OK; }
/** * worker main loop */ int swWorker_loop(swFactory *factory, int worker_id) { swServer *serv = factory->ptr; struct { long pti; swEventData req; } rdata; int n; #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_id % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set failed"); } } #endif #ifndef SW_WORKER_USE_SIGNALFD SwooleG.use_signalfd = 0; #endif //signal init swWorker_signal_init(); //worker_id SwooleWG.id = worker_id; int i; SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num); if (SwooleWG.buffer_input == NULL) { swError("malloc for SwooleWG.buffer_input failed."); return SW_ERR; } #ifndef SW_USE_RINGBUFFER int buffer_input_size; if (serv->open_eof_check || serv->open_length_check || serv->open_http_protocol) { buffer_input_size = serv->package_max_length; } else { buffer_input_size = SW_BUFFER_SIZE_BIG; } for (i = 0; i < serv->reactor_num; i++) { SwooleWG.buffer_input[i] = swString_new(buffer_input_size); if (SwooleWG.buffer_input[i] == NULL) { swError("buffer_input init failed."); return SW_ERR; } } #endif if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_id + 1; } } else { SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } int pipe_worker = serv->workers[worker_id].pipe_worker; swSetNonBlock(pipe_worker); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_EVENT_WRITE, swPipeUnsock_onWrite); } if (serv->max_request < 1) { SwooleWG.run_always = 1; } else { worker_task_num = serv->max_request; worker_task_num += swRandom(worker_id); } swWorker_onStart(serv); if (serv->ipc_mode == SW_IPC_MSGQUEUE) { while (SwooleG.running > 0) { n = serv->read_queue.out(&serv->read_queue, (swQueue_data *) &rdata, sizeof(rdata.req)); if (n < 0) { if (errno == EINTR) { if (SwooleG.signal_alarm) { SwooleG.timer.select(&SwooleG.timer); } } else { swWarn("[Worker%ld] read_queue->out() failed. Error: %s [%d]", rdata.pti, strerror(errno), errno); } continue; } swWorker_excute(factory, &rdata.req); } } else { #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); } swWorker_onStop(serv); return SW_OK; }
int swProcessPool_wait(swProcessPool *pool) { int pid, new_pid; int reload_worker_i = 0; int ret; int status; swWorker *reload_workers; reload_workers = sw_calloc(pool->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } while (SwooleG.running) { pid = wait(&status); if (pid < 0) { if (pool->reloading == 0) { swTrace("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno); } else if (pool->reload_flag == 0) { swTrace("[Manager] reload workers."); memcpy(reload_workers, pool->workers, sizeof(swWorker) * pool->worker_num); pool->reload_flag = 1; goto reload_worker; } else if (SwooleG.running == 0) { break; } } swTrace("[Manager] worker stop.pid=%d", pid); if (SwooleG.running == 1) { swWorker *exit_worker = swHashMap_find_int(pool->map, pid); if (exit_worker == NULL) { if (pool->onWorkerNotFound) { pool->onWorkerNotFound(pool, pid, status); } else { swWarn("[Manager]unknow worker[pid=%d]", pid); } continue; } if (!WIFEXITED(status)) { swWarn("worker#%d abnormal exit, status=%d, signal=%d", exit_worker->id, WEXITSTATUS(status), WTERMSIG(status)); } new_pid = swProcessPool_spawn(exit_worker); if (new_pid < 0) { swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno); sw_free(reload_workers); return SW_ERR; } swHashMap_del_int(pool->map, pid); } //reload worker reload_worker: if (pool->reloading == 1) { //reload finish if (reload_worker_i >= pool->worker_num) { pool->reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid); continue; } reload_worker_i++; } } sw_free(reload_workers); return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i; int reload_worker_i = 0; int reload_worker_num; int ret; int worker_exit_code; SwooleG.use_signalfd = 0; SwooleG.use_timerfd = 0; memset(&ManagerProcess, 0, sizeof(ManagerProcess)); swServer *serv = factory->ptr; swWorker *reload_workers; if (serv->onManagerStart) { serv->onManagerStart(serv); } reload_worker_num = serv->worker_num + SwooleG.task_worker_num; reload_workers = sw_calloc(reload_worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("malloc[reload_workers] failed"); return SW_ERR; } //for reload swSignal_add(SIGTERM, swManager_signal_handle); swSignal_add(SIGUSR1, swManager_signal_handle); swSignal_add(SIGUSR2, swManager_signal_handle); //swSignal_add(SIGINT, swManager_signal_handle); while (SwooleG.running > 0) { pid = wait(&worker_exit_code); if (pid < 0) { if (ManagerProcess.reloading == 0) { swTrace("wait() failed. Error: %s [%d]", strerror(errno), errno); } else if (ManagerProcess.reload_event_worker == 1) { memcpy(reload_workers, serv->workers, sizeof(swWorker) * serv->worker_num); reload_worker_num = serv->worker_num; if (SwooleG.task_worker_num > 0) { memcpy(reload_workers + serv->worker_num, SwooleG.task_workers.workers, sizeof(swWorker) * SwooleG.task_worker_num); reload_worker_num += SwooleG.task_worker_num; } reload_worker_i = 0; ManagerProcess.reload_event_worker = 0; goto kill_worker; } else if (ManagerProcess.reload_task_worker == 1) { if (SwooleG.task_worker_num == 0) { swWarn("Cannot reload workers, because server no have task workers."); continue; } memcpy(reload_workers, SwooleG.task_workers.workers, sizeof(swWorker) * SwooleG.task_worker_num); reload_worker_num = SwooleG.task_worker_num; reload_worker_i = 0; ManagerProcess.reload_task_worker = 0; goto kill_worker; } } if (SwooleG.running == 1) { for (i = 0; i < serv->worker_num; i++) { //compare PID if (pid != serv->workers[i].pid) { continue; } else { if (serv->onWorkerError != NULL && WEXITSTATUS(worker_exit_code) > 0) { serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code)); } pid = 0; while (1) { new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { usleep(100000); continue; } else { serv->workers[i].pid = new_pid; break; } } } } //task worker if (pid > 0) { swWorker *exit_worker = swHashMap_find_int(SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(exit_worker); } } } //reload worker kill_worker: if (ManagerProcess.reloading == 1) { //reload finish if (reload_worker_i >= reload_worker_num) { ManagerProcess.reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid); continue; } reload_worker_i++; } } sw_free(reload_workers); //kill all child process for (i = 0; i < serv->worker_num; i++) { swTrace("[Manager]kill worker processor"); kill(serv->workers[i].pid, SIGTERM); } if (SwooleG.task_worker_num > 0) { swProcessPool_shutdown(&SwooleG.task_workers); } if (serv->onManagerStop) { serv->onManagerStop(serv); } return SW_OK; }