void swProcessPool_shutdown(swProcessPool *pool) { int i, status; swWorker *worker; SwooleG.running = 0; swSignal_none(); //concurrent kill for (i = 0; i < pool->run_worker_num; i++) { worker = &pool->workers[i]; if (swKill(worker->pid, SIGTERM) < 0) { swSysError("kill(%d) failed.", worker->pid); continue; } } for (i = 0; i < pool->run_worker_num; i++) { worker = &pool->workers[i]; if (swWaitpid(worker->pid, &status, 0) < 0) { swSysError("waitpid(%d) failed.", worker->pid); } } swProcessPool_free(pool); }
/** * Use message queue ipc */ int swFactoryProcess_writer_loop_queue(swThreadParam *param) { swFactory *factory = param->object; swFactoryProcess *object = factory->object; swEventData *resp; swSendData _send; int pti = param->pti; swQueue_data sdata; //必须加1,msg_type必须不能为0 sdata.mtype = pti + 1; swSignal_none(); while (SwooleG.running > 0) { swTrace("[Writer]wt_queue[%ld]->out wait", sdata.mtype); if (object->wt_queue.out(&object->wt_queue, &sdata, sizeof(sdata.mdata)) < 0) { if (errno == EINTR) { continue; } swWarn("[writer]wt_queue->out fail.Error: %s [%d]", strerror(errno), errno); } else { resp = (swEventData *) sdata.mdata; memcpy(&_send.info, &resp->info, sizeof(resp->info)); _send.data = resp->data; swReactorThread_send(&_send); } } pthread_exit((void *) param); return SW_OK; }
static int swFactoryThread_writer_loop(swThreadParam *param) { swFactory *factory = param->object; swServer *serv = factory->ptr; swFactoryThread *this = factory->object; int pti = param->pti; int ret; swEventData *req; uint64_t flag; //cpu affinity setting #if HAVE_CPU_AFFINITY if (serv->open_cpu_affinity) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(pti % SW_CPU_NUM, &cpu_set); if (0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set)) { swTrace("pthread_setaffinity_np set fail\n"); } } #endif if (serv->onWorkerStart != NULL) { serv->onWorkerStart(serv, pti); } swSignal_none(); //main loop while (SwooleG.running > 0) { if (swRingQueue_pop(&(this->queues[pti]), (void **) &req) == 0) { factory->last_from_id = req->info.from_id; factory->onTask(factory, req); sw_free(req); } else { ret = this->writers[pti].evfd.read(&this->writers[pti].evfd, &flag, sizeof(flag)); if (ret < 0) { swTrace("read fail.errno=%d", errno); } } } //shutdown this->writers[pti].evfd.close(&this->writers[pti].evfd); if (serv->onWorkerStop != NULL) { serv->onWorkerStop(serv, pti); } sw_free(param); pthread_exit(SW_OK); return SW_OK; }
static void swFactoryThread_onStart(swThreadPool *pool, int id) { swServer *serv = SwooleG.serv; if (serv->onWorkerStart != NULL) { serv->onWorkerStart(serv, id); } swSignal_none(); SwooleTG.id = serv->reactor_num + id; SwooleTG.type = SW_THREAD_WORKER; //cpu affinity setting #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); if (serv->cpu_affinity_available_num) { CPU_SET(serv->cpu_affinity_available[id % serv->cpu_affinity_available_num], &cpu_set); } else { CPU_SET(id % SW_CPU_NUM, &cpu_set); } if (0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np() failed"); } } #endif }
/** * Use message queue ipc */ int swFactoryProcess_writer_loop_queue(swThreadParam *param) { swEventData *resp; swServer *serv = SwooleG.serv; int pti = param->pti; swQueue_data sdata; //必须加1,msg_type必须不能为0 sdata.mtype = pti + 1; swSignal_none(); while (SwooleG.running > 0) { swTrace("[Writer]wt_queue[%ld]->out wait", sdata.mtype); if (serv->write_queue.out(&serv->write_queue, &sdata, sizeof(sdata.mdata)) < 0) { if (errno == EINTR) { continue; } swWarn("[writer]wt_queue->out fail.Error: %s [%d]", strerror(errno), errno); } else { int ret; resp = (swEventData *) sdata.mdata; //Close //TODO: thread safe, should close in reactor thread. if (resp->info.len == 0) { close_fd: swServer_connection_close(SwooleG.serv, resp->info.fd, 0); continue; } else { if (resp->info.type == SW_EVENT_SENDFILE) { ret = swSocket_sendfile_sync(resp->info.fd, resp->data, SW_WRITER_TIMEOUT); } else { ret = swConnection_send_blocking(resp->info.fd, resp->data, resp->info.len, 1000 * SW_WRITER_TIMEOUT); } if (ret < 0) { switch (swConnection_error(errno)) { case SW_ERROR: swWarn("send to fd[%d] failed. Error: %s[%d]", resp->info.fd, strerror(errno), errno); break; case SW_CLOSE: goto close_fd; default: break; } } } } } pthread_exit((void *) param); return SW_OK; }