/** * Worker进程,向writer发送数据 */ int swFactoryProcess_finish(swFactory *factory, swSendData *resp) { //UDP直接在worker进程内发送 int ret, sendn, count, pipe_i; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; swReactor *reactor; int fd = resp->info.fd; //UDP在worker进程中直接发送到客户端 if(resp->info.type == SW_EVENT_UDP) { ret = swServer_send_udp_packet(serv, resp); goto finish; } //swQueue_data for msg queue struct { long pti; swEventData _send; } sdata; //写队列mtype sdata.pti = (SwooleWG.id % serv->writer_num) + 1; //copy memcpy(sdata._send.data, resp->data, resp->info.len); swConnection *conn = swServer_get_connection(serv, fd); if(conn == NULL) { swWarn("connection[%d] not found.", fd); return SW_ERR; } sdata._send.info.fd = fd; sdata._send.info.type = resp->info.type; sdata._send.info.len = resp->info.len; sdata._send.info.from_id = conn->from_id; sendn = resp->info.len + sizeof(resp->info); //swWarn("send: type=%d|content=%s", resp->info.type, resp->data); swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, fd); for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++) { #if SW_WORKER_IPC_MODE == 2 ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn); #else reactor = &(serv->reactor_threads[conn->from_id].reactor); if (serv->reactor_pipe_num > 1) { pipe_i = fd % serv->reactor_pipe_num + reactor->id; } else { pipe_i = reactor->id; } //swWarn("send to reactor. fd=%d|pipe_i=%d|reactor_id=%d|reactor_pipe_num=%d", fd, pipe_i, conn->from_id, serv->reactor_pipe_num); ret = write(object->workers[pipe_i].pipe_worker, &sdata._send, sendn); #endif //printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno); if (ret >= 0) { break; } else if (errno == EINTR) { continue; } else if (errno == EAGAIN) { swYield(); } else { break; } } finish: if (ret < 0) { swWarn("[Worker#%d]sendto writer pipe or queue failed. Error: %s [%d]", getpid(), strerror(errno), errno); } return ret; }
/** * Worker进程,向writer发送数据 */ int swFactoryProcess_finish(swFactory *factory, swSendData *resp) { //UDP直接在worker进程内发送 int ret, sendn, count;; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; //from_id超过serv->poll_thread_num,这是一个UDP //UDP在worker进程中直接发送到客户端 if(resp->info.from_id >= serv->poll_thread_num) { ret = swServer_send_udp_packet(serv, resp); goto finish; } //swQueue_data for msg queue struct { long pti; swEventData _send; } sdata; //写队列mtype sdata.pti = (c_worker_pti % serv->writer_num) + 1; //copy memcpy(sdata._send.data, resp->data, resp->info.len); sdata._send.info.fd = resp->info.fd; sdata._send.info.len = resp->info.len; sdata._send.info.from_id = resp->info.from_id; sendn = resp->info.len + sizeof(resp->info); swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, sdata._send.info.fd); for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++) { #if SW_WORKER_IPC_MODE == 2 ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn); #else ret = write(object->workers[c_worker_pti].pipe_worker, &sdata._send, sendn); #endif //printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno); if (ret >= 0) { break; } else if (errno == EINTR) { continue; } else if (errno == EAGAIN) { swYield(); } else { break; } } finish: if (ret < 0) { swWarn("[Worker#%d]sendto writer pipe or queue fail. Error: %s [%d]", getpid(), strerror(errno), errno); } return ret; }
/** * worker: send to client */ int swFactoryProcess_finish(swFactory *factory, swSendData *resp) { int ret, sendn, count; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; int fd = resp->info.fd; //unix dgram if (resp->info.type == SW_EVENT_UNIX_DGRAM) { socklen_t len; struct sockaddr_un addr_un; int from_sock = resp->info.from_fd; addr_un.sun_family = AF_UNIX; memcpy(addr_un.sun_path, resp->sun_path, resp->sun_path_len); len = sizeof(addr_un); ret = swSendto(from_sock, resp->data, resp->info.len, 0, (struct sockaddr *) &addr_un, len); goto finish; } //UDP pacakge else if (resp->info.type == SW_EVENT_UDP || resp->info.type == SW_EVENT_UDP6) { ret = swServer_send_udp_packet(serv, resp); goto finish; } //swQueue_data for msg queue struct { long pti; swEventData _send; } sdata; //for message queue sdata.pti = (SwooleWG.id % serv->writer_num) + 1; //copy memcpy(sdata._send.data, resp->data, resp->info.len); swConnection *conn = swServer_get_connection(serv, fd); if (conn == NULL || conn->active == 0) { swWarn("connection[%d] not found.", fd); return SW_ERR; } sdata._send.info.fd = fd; sdata._send.info.type = resp->info.type; sdata._send.info.len = resp->info.len; sdata._send.info.from_id = conn->from_id; sendn = resp->info.len + sizeof(resp->info); //swWarn("send: type=%d|content=%s", resp->info.type, resp->data); swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, fd); for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++) { if (serv->ipc_mode == SW_IPC_MSGQUEUE) { ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn); } else { int pipe_i; swReactor *reactor = &(serv->reactor_threads[conn->from_id].reactor); if (serv->reactor_pipe_num > 1) { pipe_i = fd % serv->reactor_pipe_num + reactor->id; } else { pipe_i = reactor->id; } //swWarn("send to reactor. fd=%d|pipe_i=%d|reactor_id=%d|reactor_pipe_num=%d", fd, pipe_i, conn->from_id, serv->reactor_pipe_num); ret = write(object->workers[pipe_i].pipe_worker, &sdata._send, sendn); } //printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno); if (ret >= 0) { break; } else if (errno == EINTR) { continue; } else if (errno == EAGAIN) { swYield(); } else { break; } } finish: if (ret < 0) { swWarn("[Worker#%d]sendto writer pipe or queue failed. Error: %s [%d]", getpid(), strerror(errno), errno); } return ret; }