SWINLINE swBuffer_trunk* swConnection_get_out_buffer(swConnection *conn, uint32_t type) { swBuffer_trunk *trunk; if (conn->out_buffer == NULL) { conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE); if (conn->out_buffer == NULL) { return NULL; } } if (type == SW_TRUNK_SENDFILE) { trunk = swBuffer_new_trunk(conn->out_buffer, SW_TRUNK_SENDFILE, 0); } else { trunk = swBuffer_get_trunk(conn->out_buffer); if (trunk == NULL) { trunk = swBuffer_new_trunk(conn->out_buffer, SW_TRUNK_DATA, conn->out_buffer->trunk_size); } } return trunk; }
SWINLINE swBuffer_trunk* swConnection_get_in_buffer(swConnection *conn) { swBuffer_trunk *trunk = NULL; swBuffer *buffer; if (conn->in_buffer == NULL) { buffer = swBuffer_new(SW_BUFFER_SIZE); //buffer create failed if (buffer == NULL) { return NULL; } //new trunk trunk = swBuffer_new_trunk(buffer, SW_TRUNK_DATA, buffer->trunk_size); if (trunk == NULL) { sw_free(buffer); return NULL; } conn->in_buffer = buffer; } else { buffer = conn->in_buffer; trunk = buffer->tail; if (trunk == NULL || trunk->length == buffer->trunk_size) { trunk = swBuffer_new_trunk(buffer, SW_TRUNK_DATA, buffer->trunk_size); } } return trunk; }
int swClient_tcp_send_async(swClient *cli, char *data, int length) { if (cli->out_buffer == NULL) { cli->out_buffer = swBuffer_new(SW_BUFFER_SIZE); if (cli->out_buffer == NULL) { return SW_ERR; } } if (swBuffer_empty(cli->out_buffer)) { SwooleG.main_reactor->set(SwooleG.main_reactor, cli->sock, cli->reactor_fdtype | SW_EVENT_READ | SW_EVENT_WRITE); } /** * append data to buffer */ if (swBuffer_append(cli->out_buffer, data, length) < 0) { return SW_ERR; } return SW_OK; }
int swClient_tcp_send_async(swClient *cli, char *data, int length) { if (cli->out_buffer == NULL) { cli->out_buffer = swBuffer_new(SW_BUFFER_SIZE); if (cli->out_buffer == NULL) { return SW_ERR; } } swSendData _send; _send.info.fd = cli->sock; _send.info.len = length; _send.data = data; if (swBuffer_empty(cli->out_buffer)) { SwooleG.main_reactor->set(SwooleG.main_reactor, cli->sock, cli->reactor_fdtype | SW_EVENT_READ | SW_EVENT_WRITE); } if (swBuffer_in(cli->out_buffer, &_send) < 0) { return SW_ERR; } return SW_OK; }
int swReactor_write(swReactor *reactor, int fd, void *buf, int n) { int ret; swConnection *socket = swReactor_get(reactor, fd); swBuffer *buffer = socket->out_buffer; assert(fd > 2); if (socket->fd == 0) { socket->fd = fd; } if (swBuffer_empty(buffer)) { do_send: ret = swConnection_send(socket, buf, n, 0); if (ret > 0) { if (n == ret) { return ret; } else { buf += ret; n -= ret; goto do_buffer; } } #ifdef HAVE_KQUEUE else if (errno == EAGAIN || errno == ENOBUFS) #else else if (errno == EAGAIN) #endif { do_buffer: if (!socket->out_buffer) { buffer = swBuffer_new(sizeof(swEventData)); if (!buffer) { swWarn("create worker buffer failed."); return SW_ERR; } socket->out_buffer = buffer; } socket->events |= SW_EVENT_WRITE; if (socket->events & SW_EVENT_READ) { if (reactor->set(reactor, fd, socket->fdtype | socket->events) < 0) { swSysError("reactor->set(%d, SW_EVENT_WRITE) failed.", fd); } } else { if (reactor->add(reactor, fd, socket->fdtype | SW_EVENT_WRITE) < 0) { swSysError("reactor->add(%d, SW_EVENT_WRITE) failed.", fd); } } goto append_buffer; } else if (errno == EINTR) { goto do_send; } else { return SW_ERR; } } else {