/** * receive data from reactor */ static int swFactoryProcess_worker_onPipeReceive(swReactor *reactor, swEvent *event) { swEventData task; swServer *serv = reactor->ptr; swFactory *factory = &serv->factory; int ret; read_from_pipe: if (read(event->fd, &task, sizeof(task)) > 0) { /** * Big package */ ret = swFactoryProcess_worker_excute(factory, &task); if (task.info.type == SW_EVENT_PACKAGE_START) { //no data if (ret < 0 && errno == EAGAIN) { return SW_OK; } else if (ret > 0) { goto read_from_pipe; } } return ret; } return SW_ERR; }
/** * receive data from reactor */ static int swFactoryProcess_worker_onPipeReceive(swReactor *reactor, swEvent *event) { swEventData task; swServer *serv = reactor->ptr; swFactory *factory = &serv->factory; if (read(event->fd, &task, sizeof(task)) > 0) { return swFactoryProcess_worker_excute(factory, &task); } return SW_ERR; }
static int swFactoryProcess_worker_receive(swReactor *reactor, swEvent *event) { int n; swEventData task; swServer *serv = reactor->ptr; swFactory *factory = &serv->factory; do { n = read(event->fd, &task, sizeof(task)); } while(n < 0 && errno == EINTR); return swFactoryProcess_worker_excute(factory, &task); }
static int swFactoryProcess_worker_receive(swReactor *reactor, swEvent *event) { int n, i, ret = -1; swEventData task; swServer *serv = reactor->ptr; swFactory *factory = &serv->factory; for (i = 0; i < SW_WORKER_READ_COUNT; i++) { n = read(event->fd, &task, sizeof(task)); if (n > 0) { ret = swFactoryProcess_worker_excute(factory, &task); } else if (errno == EAGAIN) { break; } } return ret; }
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; }
/** * 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; }