int swPipeBase_create(swPipe *p, int blocking) { int ret; swPipeBase *object = sw_malloc(sizeof(swPipeBase)); if (object == NULL) { return -1; } p->blocking = blocking; ret = pipe(object->pipes); if (ret < 0) { swWarn("pipe create fail. Error: %s[%d]", strerror(errno), errno); return -1; } else { //Nonblock if(blocking == 0) { swSetNonBlock(object->pipes[0]); swSetNonBlock(object->pipes[1]); } p->object = object; p->read = swPipeBase_read; p->write = swPipeBase_write; p->getFd = swPipeBase_getFd; p->close = swPipeBase_close; } return 0; }
int swPipeUnsock_create(swPipe *p, int blocking, int protocol) { int ret; swPipeUnsock *object = sw_malloc(sizeof(swPipeUnsock)); if (object == NULL) { return -1; } p->blocking = blocking; ret = socketpair(PF_LOCAL, protocol, 0, object->socks); if (ret < 0) { return -1; } else { //Nonblock if (blocking == 0) { swSetNonBlock(object->socks[0]); swSetNonBlock(object->socks[1]); } p->object = object; p->read = swPipeUnsock_read; p->write = swPipeUnsock_write; p->getFd = swPipeUnsock_getFd; p->close = swPipeUnsock_close; } return 0; }
int swClient_tcp_connect(swClient *cli, char *host, int port, float timeout, int nonblock) { int ret; cli->serv_addr.sin_family = cli->sock_domain; cli->serv_addr.sin_port = htons(port); cli->serv_addr.sin_addr.s_addr = inet_addr(host); cli->timeout = timeout; swSetTimeout(cli->sock, timeout); if(nonblock == 1) { swSetNonBlock(cli->sock); } else { swSetBlock(cli->sock); } while (1) { ret = connect(cli->sock, (struct sockaddr *) (&cli->serv_addr), sizeof(cli->serv_addr)); if (ret < 0) { if (errno == EINTR) { continue; } } break; } return ret; }
int swSocket_bind(int type, char *host, int port) { int sock; int ret; struct sockaddr_in addr_in4; struct sockaddr_in6 addr_in6; struct sockaddr_un addr_un; sock = swSocket_create(type); if (sock < 0) { swSysError("create socket failed."); return SW_ERR; } int option = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int)) < 0) { swSysError("setsockopt(%d, SO_REUSEADDR) failed.", sock); } //unix socket if (type == SW_SOCK_UNIX_DGRAM || type == SW_SOCK_UNIX_STREAM) { bzero(&addr_un, sizeof(addr_un)); unlink(host); addr_un.sun_family = AF_UNIX; strcpy(addr_un.sun_path, host); ret = bind(sock, (struct sockaddr*) &addr_un, sizeof(addr_un)); } //IPv6 else if (type > SW_SOCK_UDP) { bzero(&addr_in6, sizeof(addr_in6)); inet_pton(AF_INET6, host, &(addr_in6.sin6_addr)); addr_in6.sin6_port = htons(port); addr_in6.sin6_family = AF_INET6; ret = bind(sock, (struct sockaddr *) &addr_in6, sizeof(addr_in6)); } //IPv4 else { bzero(&addr_in4, sizeof(addr_in4)); inet_pton(AF_INET, host, &(addr_in4.sin_addr)); addr_in4.sin_port = htons(port); addr_in4.sin_family = AF_INET; ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof(addr_in4)); } //bind failed if (ret < 0) { swWarn("bind(%s:%d) failed. Error: %s [%d]", host, port, strerror(errno), errno); return SW_ERR; } if (type == SW_SOCK_UDP || type == SW_SOCK_UDP6 || type == SW_SOCK_UNIX_DGRAM) { return sock; } swSetNonBlock(sock); return sock; }
SWINLINE int swAccept(int server_socket, struct sockaddr_in *addr, int addr_len) { int conn_fd; bzero(addr, addr_len); while (1) { #ifdef SW_USE_ACCEPT4 conn_fd = accept4(server_socket, (struct sockaddr *) addr, (socklen_t *) &addr_len, SOCK_NONBLOCK); #else conn_fd = accept(server_socket, (struct sockaddr *) addr, (socklen_t *) &addr_len); #endif if (conn_fd < 0) { //中断 if (errno == EINTR) { continue; } else { swTrace("accept fail. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } } #ifndef SW_USE_ACCEPT4 swSetNonBlock(conn_fd); #endif break; } return conn_fd; }
/** * 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; }
int swSocket_listen(int type, char *host, int port, int backlog) { int sock; int option; int ret; struct sockaddr_in addr_in4; struct sockaddr_in6 addr_in6; sock = swSocket_create(type); if (sock < 0) { swWarn("swSocket_listen: Create socket fail.type=%d|Errno=%d", type, errno); return SW_ERR; } //reuse option = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int)); //IPv6 if (type > SW_SOCK_UDP) { bzero(&addr_in6, sizeof(addr_in6)); inet_pton(AF_INET6, host, &(addr_in6.sin6_addr)); addr_in6.sin6_port = htons(port); addr_in6.sin6_family = AF_INET6; ret = bind(sock, (struct sockaddr *) &addr_in6, sizeof(addr_in6)); } //IPv4 else { bzero(&addr_in4, sizeof(addr_in4)); inet_pton(AF_INET, host, &(addr_in4.sin_addr)); addr_in4.sin_port = htons(port); addr_in4.sin_family = AF_INET; ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof(addr_in4)); } //将监听套接字同sockaddr绑定 if (ret < 0) { swWarn("bind fail.type=%d|host=%s|port=%d|Errno=%d\n", type, host, port, errno); return SW_ERR; } if (type == SW_SOCK_UDP || type == SW_SOCK_UDP6) { return sock; } //开始监听套接字 ret = listen(sock, backlog); if (ret < 0) { swWarn("Listen fail.type=%d|host=%s|port=%d|Errno=%d\n", type, host, port, errno); return SW_ERR; } swSetNonBlock(sock); return sock; }
static int swClient_tcp_connect_sync(swClient *cli, char *host, int port, double timeout, int nonblock) { int ret; cli->timeout = timeout; if (swClient_inet_addr(cli, host, port) < 0) { return SW_ERR; } if (nonblock == 1) { swSetNonBlock(cli->socket->fd); } else { if (cli->timeout > 0) { swSocket_set_timeout(cli->socket->fd, timeout); } swSetBlock(cli->socket->fd); } while (1) { ret = connect(cli->socket->fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); if (ret < 0) { if (errno == EINTR) { continue; } } break; } if (ret >= 0) { cli->socket->active = 1; #ifdef SW_USE_OPENSSL if (cli->open_ssl) { if (swClient_enable_ssl_encrypt(cli) < 0) { return SW_ERR; } if (swClient_ssl_handshake(cli) < 0) { return SW_ERR; } } #endif } return ret; }
/** * no use */ int swServer_reactor_add(swServer *serv, int fd, int sock_type) { int poll_id = (serv->reactor_round_i++) % serv->reactor_num; swReactor *reactor = &(serv->reactor_threads[poll_id].reactor); swSetNonBlock(fd); //must be nonblock if(sock_type == SW_SOCK_TCP || sock_type == SW_SOCK_TCP6) { reactor->add(reactor, fd, SW_FD_TCP); } else { reactor->add(reactor, fd, SW_FD_UDP); } return SW_OK; }
int static cpListen() { int sock; int option; int ret; struct sockaddr_in addr_in4; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) { cpLog("swSocket_listen: Create socket fail.Errno=%d", errno); return FAILURE; } option = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof (int)); bzero(&addr_in4, sizeof (addr_in4)); inet_pton(AF_INET, "127.0.0.1", &(addr_in4.sin_addr)); addr_in4.sin_port = htons(CPGC.port); addr_in4.sin_family = AF_INET; ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof (addr_in4)); if (ret < 0) { cpLog("Bind fail.port=%d. Error: %s [%d]", CPGC.port, strerror(errno), errno); return FAILURE; } //开始监听套接字 ret = listen(sock, CPGC.backlog); if (ret < 0) { cpLog("Listen fail.port=%d. Error: %s [%d]", CPGC.port, strerror(errno), errno); return FAILURE; } swSetNonBlock(sock); if (sock < 0) { return FAILURE; } int bufsize = CP_UNSOCK_BUFSIZE; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof (bufsize)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof (bufsize)); return sock; }
int swReactor_accept(swReactor *reactor, swDataHead *event) { swEventConnect conn_ev; conn_ev.from_id = event->from_id; conn_ev.serv_fd = event->fd; conn_ev.addrlen = sizeof(conn_ev.addr); bzero(&conn_ev.addr, conn_ev.addrlen); conn_ev.conn_fd = accept(conn_ev.serv_fd, (struct sockaddr *) &conn_ev.addr, &conn_ev.addrlen); if (conn_ev.conn_fd < 0) { swTrace("[swReactorEpollWait]accept fail\n"); return -1; } swSetNonBlock(conn_ev.conn_fd); reactor->add(reactor, conn_ev.conn_fd, SW_FD_TCP); return conn_ev.conn_fd; }
int swClient_tcp_connect(swClient *cli, char *host, int port, double timeout, int nonblock) { int ret; cli->serv_addr.sin_family = cli->sock_domain; cli->serv_addr.sin_port = htons(port); if (swClient_inet_addr(cli, host) < 0) { return SW_ERR; } cli->timeout = timeout; if (nonblock == 1) { swSetNonBlock(cli->sock); } else { swSetTimeout(cli->sock, timeout); //block default //swSetBlock(cli->sock); } while (1) { ret = connect(cli->sock, (struct sockaddr *) (&cli->serv_addr), sizeof(cli->serv_addr)); if (ret < 0) { if (errno == EINTR) { continue; } } break; } if (ret >= 0) { cli->connected = 1; } return ret; }
static int swClient_tcp_connect(swClient *cli, char *host, int port, double timeout, int nonblock) { int ret; cli->timeout = timeout; if (swClient_inet_addr(cli, host, port) < 0) { return SW_ERR; } if (nonblock == 1) { swSetNonBlock(cli->connection.fd); } else { if (cli->timeout > 0) { swSetTimeout(cli->connection.fd, timeout); } swSetBlock(cli->connection.fd); } while (1) { ret = connect(cli->connection.fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); if (ret < 0) { if (errno == EINTR) { continue; } } break; } if (ret >= 0) { cli->connection.active = 1; } return ret; }
void swWorker_onStart(swServer *serv) { /** * Release other worker process */ swWorker *worker; if (SwooleWG.id >= serv->worker_num) { SwooleG.process_type = SW_PROCESS_TASKWORKER; } else { SwooleG.process_type = SW_PROCESS_WORKER; } SwooleWG.worker = swServer_get_worker(serv, SwooleWG.id); int i; for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++) { worker = swServer_get_worker(serv, i); if (SwooleWG.id == i) { continue; } else { swWorker_free(worker); } if (swIsWorker()) { swSetNonBlock(worker->pipe_master); } } if (serv->onWorkerStart) { serv->onWorkerStart(serv, SwooleWG.id); } }
int swServer_onAccept(swReactor *reactor, swEvent *event) { swServer *serv = reactor->ptr; int clilen; int conn_fd; int ret; struct sockaddr_in clientaddr; clilen = sizeof(clientaddr); bzero(&clientaddr, clilen); swTrace("[Main]accept start\n"); //得到连接套接字 conn_fd = accept(serv->sock, (struct sockaddr *) &clientaddr, (socklen_t *) &clilen); if (conn_fd < 0) { swTrace("[Main]accept fail Errno=%d|SockFD=%d|\n", errno, serv->sock); return SW_ERR; } swTrace("[Main]swSetNonBlock\n"); swSetNonBlock(conn_fd); char *str; str = inet_ntoa(clientaddr.sin_addr); swTrace("[Main]connect from %s, by process %d\n", str, getpid()); if (serv->c_pti >= serv->poll_thread_num) { serv->c_pti = 0; } ret = serv->threads[serv->c_pti].reactor.add(&(serv->threads[serv->c_pti].reactor), conn_fd, SW_FD_CONN); if (ret < 0) { swTrace("[Main]add event fail Errno=%d|FD=%d\n", errno, conn_fd); return SW_ERR; } serv->onConnect(serv, conn_fd, serv->c_pti); serv->c_pti++; return SW_OK; }
int swSocket_listen(int type, char *host, int port, int backlog) { int sock; int option; int ret; struct sockaddr_in addr_in4; struct sockaddr_in6 addr_in6; struct sockaddr_un addr_un; sock = swSocket_create(type); if (sock < 0) { swWarn("swSocket_listen: Create socket fail.type=%d|Errno=%d", type, errno); return SW_ERR; } //reuse option = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int)); //unix socket if (type == SW_SOCK_UNIX_DGRAM || type == SW_SOCK_UNIX_STREAM) { bzero(&addr_un, sizeof(addr_un)); unlink(host); addr_un.sun_family = AF_UNIX; strcpy(addr_un.sun_path, host); ret = bind(sock, (struct sockaddr*)&addr_un, sizeof(addr_un)); } //IPv6 else if (type > SW_SOCK_UDP) { bzero(&addr_in6, sizeof(addr_in6)); inet_pton(AF_INET6, host, &(addr_in6.sin6_addr)); addr_in6.sin6_port = htons(port); addr_in6.sin6_family = AF_INET6; ret = bind(sock, (struct sockaddr *) &addr_in6, sizeof(addr_in6)); } //IPv4 else { bzero(&addr_in4, sizeof(addr_in4)); inet_pton(AF_INET, host, &(addr_in4.sin_addr)); addr_in4.sin_port = htons(port); addr_in4.sin_family = AF_INET; ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof(addr_in4)); } //bind failed if (ret < 0) { swWarn("Bind failed. type=%d|host=%s|port=%d. Error: %s [%d]", type, host, port, strerror(errno), errno); return SW_ERR; } if (type == SW_SOCK_UDP || type == SW_SOCK_UDP6 || type == SW_SOCK_UNIX_DGRAM) { return sock; } //listen stream socket ret = listen(sock, backlog); if (ret < 0) { swWarn("Listen fail.type=%d|host=%s|port=%d. Error: %s [%d]", type, host, port, strerror(errno), errno); return SW_ERR; } swSetNonBlock(sock); return sock; }
int swClient_create(swClient *cli, int type, int async) { int _domain; int _type; bzero(cli, sizeof(*cli)); switch (type) { case SW_SOCK_TCP: _domain = AF_INET; _type = SOCK_STREAM; break; case SW_SOCK_TCP6: _domain = AF_INET6; _type = SOCK_STREAM; break; case SW_SOCK_UNIX_STREAM: _domain = AF_UNIX; _type = SOCK_STREAM; break; case SW_SOCK_UDP: _domain = AF_INET; _type = SOCK_DGRAM; break; case SW_SOCK_UDP6: _domain = AF_INET6; _type = SOCK_DGRAM; break; case SW_SOCK_UNIX_DGRAM: _domain = AF_UNIX; _type = SOCK_DGRAM; break; default: return SW_ERR; } int sockfd = socket(_domain, _type, 0); if (sockfd < 0) { swWarn("socket() failed. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } if (async) { cli->socket = swReactor_get(SwooleG.main_reactor, sockfd); } else { cli->socket = sw_malloc(sizeof(swConnection)); } cli->buffer_input_size = SW_CLIENT_BUFFER_SIZE; if (!cli->socket) { swWarn("malloc(%d) failed.", (int ) sizeof(swConnection)); return SW_ERR; } bzero(cli->socket, sizeof(swConnection)); cli->socket->fd = sockfd; cli->socket->object = cli; if (async) { swSetNonBlock(cli->socket->fd); if (isset_event_handle == 0) { SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_STREAM_CLIENT | SW_EVENT_READ, swClient_onStreamRead); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_DGRAM_CLIENT | SW_EVENT_READ, swClient_onDgramRead); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE, swClient_onWrite); isset_event_handle = 1; } } if (swSocket_is_stream(type)) { cli->recv = swClient_tcp_recv_no_buffer; if (async) { cli->connect = swClient_tcp_connect_async; cli->send = swClient_tcp_send_async; cli->sendfile = swClient_tcp_sendfile_async; } else { cli->connect = swClient_tcp_connect_sync; cli->send = swClient_tcp_send_sync; cli->sendfile = swClient_tcp_sendfile_sync; } } else { cli->connect = swClient_udp_connect; cli->recv = swClient_udp_recv; cli->send = swClient_udp_send; } cli->_sock_domain = _domain; cli->_sock_type = _type; cli->close = swClient_close; cli->type = type; cli->async = async; return SW_OK; }
int swSocket_listen(int type, char *host, int port, int backlog) { int sock; int option; int ret; struct sockaddr_in addr_in4; struct sockaddr_in6 addr_in6; struct sockaddr_un addr_un; sock = swSocket_create(type); if (sock < 0) { swSysError("create socket failed."); return SW_ERR; } //reuse address option = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int)) < 0) { swSysError("setsockopt(SO_REUSEPORT) failed."); } //reuse port #ifdef HAVE_REUSEPORT if (SwooleG.reuse_port) { if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(int)) < 0) { swSysError("setsockopt(SO_REUSEPORT) failed."); SwooleG.reuse_port = 0; } } #endif //unix socket if (type == SW_SOCK_UNIX_DGRAM || type == SW_SOCK_UNIX_STREAM) { bzero(&addr_un, sizeof(addr_un)); unlink(host); addr_un.sun_family = AF_UNIX; strcpy(addr_un.sun_path, host); ret = bind(sock, (struct sockaddr*) &addr_un, sizeof(addr_un)); } //IPv6 else if (type > SW_SOCK_UDP) { bzero(&addr_in6, sizeof(addr_in6)); inet_pton(AF_INET6, host, &(addr_in6.sin6_addr)); addr_in6.sin6_port = htons(port); addr_in6.sin6_family = AF_INET6; ret = bind(sock, (struct sockaddr *) &addr_in6, sizeof(addr_in6)); } //IPv4 else { bzero(&addr_in4, sizeof(addr_in4)); inet_pton(AF_INET, host, &(addr_in4.sin_addr)); addr_in4.sin_port = htons(port); addr_in4.sin_family = AF_INET; ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof(addr_in4)); } //bind failed if (ret < 0) { swWarn("bind(%s:%d) failed. Error: %s [%d]", host, port, strerror(errno), errno); return SW_ERR; } if (type == SW_SOCK_UDP || type == SW_SOCK_UDP6 || type == SW_SOCK_UNIX_DGRAM) { return sock; } //listen stream socket ret = listen(sock, backlog); if (ret < 0) { swWarn("listen(%s:%d, %d) failed. Error: %s[%d]", host, port, backlog, strerror(errno), errno); return SW_ERR; } swSetNonBlock(sock); return sock; }
static int swClient_tcp_connect_sync(swClient *cli, char *host, int port, double timeout, int nonblock) { int ret, n; char buf[1024]; cli->timeout = timeout; if (swClient_inet_addr(cli, host, port) < 0) { return SW_ERR; } if (nonblock == 1) { swSetNonBlock(cli->socket->fd); } else { if (cli->timeout > 0) { swSocket_set_timeout(cli->socket->fd, timeout); } swSetBlock(cli->socket->fd); } while (1) { ret = connect(cli->socket->fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); if (ret < 0) { if (errno == EINTR) { continue; } } break; } if (ret >= 0) { cli->socket->active = 1; //socks5 proxy if (cli->socks5_proxy) { swSocks5_pack(buf, cli->socks5_proxy->username == NULL ? 0x00 : 0x02); if (cli->send(cli, buf, 3, 0) < 0) { return SW_ERR; } cli->socks5_proxy->state = SW_SOCKS5_STATE_HANDSHAKE; while (1) { n = cli->recv(cli, buf, sizeof(buf), 0); if (n > 0) { if (swSocks5_connect(cli, buf, n) < 0) { return SW_ERR; } else { if (cli->socks5_proxy->state == SW_SOCKS5_STATE_READY) { break; } else { continue; } } } return SW_ERR; } } #ifdef SW_USE_OPENSSL if (cli->open_ssl) { if (swClient_enable_ssl_encrypt(cli) < 0) { return SW_ERR; } if (swClient_ssl_handshake(cli) < 0) { return SW_ERR; } } #endif } return ret; }
/** * 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; }
void swWorker_onStart(swServer *serv) { /** * Release other worker process */ int i; swWorker *worker; if (SwooleWG.id >= serv->worker_num) { SwooleG.process_type = SW_PROCESS_TASKWORKER; } else { SwooleG.process_type = SW_PROCESS_WORKER; } SwooleWG.worker = swServer_get_worker(serv, SwooleWG.id); if (swIsWorker()) { int maxfd; if (SwooleG.task_worker_num > 0) { maxfd = SwooleG.task_workers.workers[SwooleG.task_worker_num - 1].pipe_master + 1; } else { maxfd = serv->workers[serv->worker_num - 1].pipe_master + 1; } SwooleWG.fd_map = swArray_new(maxfd, sizeof(swPipe *), 0); } for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++) { worker = swServer_get_worker(serv, i); if (SwooleWG.id == i) { continue; } else { swWorker_free(worker); } if (SwooleWG.id < serv->worker_num && i < serv->worker_num) { close(worker->pipe_worker); } if (swIsWorker()) { swSetNonBlock(worker->pipe_master); swArray_store(SwooleWG.fd_map, worker->pipe_master, &worker->pipe_object); worker->pipe_object->pipe_used = worker->pipe_master; } } if (serv->onWorkerStart) { serv->onWorkerStart(serv, SwooleWG.id); } }
/** * 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; }
void swWorker_onStart(swServer *serv) { /** * Release other worker process */ swWorker *worker; if (SwooleWG.id >= serv->worker_num) { SwooleG.process_type = SW_PROCESS_TASKWORKER; } else { SwooleG.process_type = SW_PROCESS_WORKER; } int is_root = !geteuid(); struct passwd *passwd = NULL; struct group *group = NULL; if (is_root) { //get group info if (SwooleG.group) { group = getgrnam(SwooleG.group); if (!group) { swWarn("get group [%s] info failed.", SwooleG.group); } } //get user info if (SwooleG.user) { passwd = getpwnam(SwooleG.user); if (!passwd) { swWarn("get user [%s] info failed.", SwooleG.user); } } //chroot if (SwooleG.chroot) { if (0 > chroot(SwooleG.chroot)) { swSysError("chroot to [%s] failed.", SwooleG.chroot); } } //set process group if (SwooleG.group && group) { if (setgid(group->gr_gid) < 0) { swSysError("setgid to [%s] failed.", SwooleG.group); } } //set process user if (SwooleG.user && passwd) { if (setuid(passwd->pw_uid) < 0) { swSysError("setuid to [%s] failed.", SwooleG.user); } } } SwooleWG.worker = swServer_get_worker(serv, SwooleWG.id); int i; for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++) { worker = swServer_get_worker(serv, i); if (SwooleWG.id == i) { continue; } else { swWorker_free(worker); } if (swIsWorker()) { swSetNonBlock(worker->pipe_master); } } if (serv->onWorkerStart) { serv->onWorkerStart(serv, SwooleWG.id); } }
static PHP_METHOD(swoole_mysql, __construct) { if (!mysql_request_buffer) { mysql_request_buffer = swString_new(SW_MYSQL_QUERY_INIT_SIZE); if (!mysql_request_buffer) { swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); RETURN_FALSE; } } char *unixsocket = NULL; zend_size_t unixsocket_len = 0; mysql_connector connector; connector.port = SW_MYSQL_DEFAULT_PORT; if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "ssss|ls", &connector.host, &connector.host_len, &connector.user, &connector.user_len, &connector.password, &connector.password_len, &connector.database, &connector.database_len, &connector.port, &unixsocket, &unixsocket_len) == FAILURE) { RETURN_FALSE; } swClient *cli = emalloc(sizeof(swClient)); int type = SW_SOCK_TCP; if (unixsocket) { type = SW_SOCK_UNIX_STREAM; connector.host = unixsocket; connector.host_len = unixsocket_len; } if (swClient_create(cli, type, 0) < 0) { zend_throw_exception(swoole_mysql_exception_class_entry, "swClient_create failed.", 1 TSRMLS_CC); RETURN_FALSE; } if (cli->connect(cli, connector.host, connector.port, SW_MYSQL_CONNECT_TIMEOUT, 0) < 0) { zend_throw_exception(swoole_mysql_exception_class_entry, "connect to mysql server[%s:%d] failed.", 2 TSRMLS_CC); RETURN_FALSE; } int tcp_nodelay = 1; if (setsockopt(cli->socket->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &tcp_nodelay, sizeof(int)) == -1) { swoole_php_sys_error(E_WARNING, "setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) failed.", cli->socket->fd); } char buf[2048]; int n = cli->recv(cli, buf, sizeof(buf), 0); if (n < 0) { zend_throw_exception(swoole_mysql_exception_class_entry, "recvfrom mysql server failed.", 3 TSRMLS_CC); RETURN_FALSE; } if (mysql_handshake(&connector, buf, n) == SW_ERR) { zend_throw_exception(swoole_mysql_exception_class_entry, "handshake with mysql server failed.", 4 TSRMLS_CC); RETURN_FALSE; } if (cli->send(cli, connector.buf, connector.packet_length + 4, 0) < 0) { zend_throw_exception(swoole_mysql_exception_class_entry, "sendto mysql server failed.", 5 TSRMLS_CC); RETURN_FALSE; } if (cli->recv(cli, buf, sizeof(buf), 0) < 0) { zend_throw_exception(swoole_mysql_exception_class_entry, "recvfrom mysql server failed.", 6 TSRMLS_CC); RETURN_FALSE; } mysql_client *client = emalloc(sizeof(mysql_client)); bzero(client, sizeof(mysql_client)); client->buffer = swString_new(SW_BUFFER_SIZE_BIG); client->fd = cli->socket->fd; client->object = getThis(); client->cli = cli; sw_copy_to_stack(client->object, client->_object); zend_update_property_bool(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("connected"), 1 TSRMLS_CC); swoole_set_object(getThis(), client); php_swoole_check_reactor(); swSetNonBlock(cli->socket->fd); if (!isset_event_callback) { SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL | SW_EVENT_READ, swoole_mysql_onRead); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL | SW_EVENT_ERROR, swoole_mysql_onError); } swConnection *socket = swReactor_get(SwooleG.main_reactor, cli->socket->fd); socket->active = 1; socket->object = client; }
/** * 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 */ 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; }