/** * send buffer to client */ int swConnection_buffer_send(swConnection *conn) { int ret, sendn; swBuffer *buffer = conn->out_buffer; swBuffer_trunk *trunk = swBuffer_get_trunk(buffer); sendn = trunk->length - trunk->offset; if (sendn == 0) { swBuffer_pop_trunk(buffer, trunk); return SW_CONTINUE; } ret = swConnection_send(conn, trunk->store.ptr + trunk->offset, sendn, 0); //printf("BufferOut: reactor=%d|sendn=%d|ret=%d|trunk->offset=%d|trunk_len=%d\n", reactor->id, sendn, ret, trunk->offset, trunk->length); if (ret < 0) { switch (swConnection_error(conn->fd, errno)) { case SW_ERROR: swWarn("send to fd[%d] failed. Error: %s[%d]", conn->fd, strerror(errno), errno); return SW_OK; case SW_CLOSE: return SW_CLOSE; case SW_WAIT: return SW_WAIT; default: return SW_CONTINUE; } } //trunk full send else if(ret == sendn || sendn == 0) { swBuffer_pop_trunk(buffer, trunk); } else { trunk->offset += ret; } return SW_CONTINUE; }
/** * send buffer to client */ int swBuffer_send(swBuffer *buffer, int fd) { int ret, sendn; swBuffer_trunk *trunk = swBuffer_get_trunk(buffer); sendn = trunk->length - trunk->offset; if (sendn == 0) { swBuffer_pop_trunk(buffer, trunk); return SW_CONTINUE; } ret = send(fd, trunk->data + trunk->offset, sendn, 0); //printf("BufferOut: reactor=%d|sendn=%d|ret=%d|trunk->offset=%d|trunk_len=%d\n", reactor->id, sendn, ret, trunk->offset, trunk->length); if (ret < 0) { if (swConnection_error(fd, errno) < 0) { return SW_CLOSE; } else if(errno == EAGAIN) { return SW_WAIT; } else { swWarn("send to fd[%d] failed. Error: %s[%d]", fd, strerror(errno), errno); return SW_CONTINUE; } } //trunk full send else if(ret == sendn || sendn == 0) { swBuffer_pop_trunk(buffer, trunk); } else { trunk->offset += ret; } return SW_CONTINUE; }
int swConnection_send_in_buffer(swConnection *conn) { int ret; #ifdef SW_DEBUG int i; #endif swFactory *factory = SwooleG.factory; swEventData _send; swBuffer *buffer = conn->in_buffer; swBuffer_trunk *trunk = swBuffer_get_trunk(buffer); _send.info.fd = conn->fd; _send.info.type = (buffer->trunk_num == 1) ? SW_EVENT_TCP : SW_EVENT_PACKAGE_START; _send.info.from_id = conn->from_id; while (trunk != NULL) { _send.info.len = trunk->length; memcpy(_send.data, trunk->data, _send.info.len); ret = factory->dispatch(factory, &_send); //TODO: 处理数据失败,数据将丢失 if (ret < 0) { swWarn("factory->dispatch failed."); } swBuffer_pop_trunk(buffer, trunk); trunk = swBuffer_get_trunk(buffer); swTrace("send2worker[i=%d][trunk_num=%d][type=%d]\n", i++, buffer->trunk_num, _send.info.type); if (_send.info.type == SW_EVENT_PACKAGE_START) { _send.info.type = SW_EVENT_PACKAGE_TRUNK; } //package end if (trunk == NULL || trunk->next == NULL) { _send.info.type = SW_EVENT_PACKAGE_END; } } return SW_OK; }
int swConnection_send_in_buffer(swConnection *conn) { swFactory *factory = SwooleG.factory; swEventData _send; _send.info.fd = conn->fd; _send.info.from_id = conn->from_id; #ifdef SW_USE_RINGBUFFER swServer *serv = SwooleG.serv; swMemoryPool *pool = serv->reactor_threads[conn->from_id].pool; swPackage package; package.length = 0; while (1) { package.data = pool->alloc(pool, buffer->length); if (package.data == NULL) { swYield(); swWarn("reactor memory pool full."); continue; } break; } _send.info.type = SW_EVENT_PACKAGE; while (trunk != NULL) { _send.info.len = trunk->length; memcpy(package.data + package.length , trunk->data, trunk->length); package.length += trunk->length; swBuffer_pop_trunk(buffer, trunk); trunk = swBuffer_get_trunk(buffer); } _send.info.len = sizeof(package); memcpy(_send.data, &package, sizeof(package)); //swWarn("[ReactorThread] copy_n=%d", package.length); return factory->dispatch(factory, &_send); #else swBuffer *buffer = conn->in_buffer; swBuffer_trunk *trunk = swBuffer_get_trunk(buffer); int ret; _send.info.type = SW_EVENT_PACKAGE_START; /** * lock target */ SwooleTG.factory_lock_target = 1; while (trunk != NULL) { _send.info.len = trunk->length; memcpy(_send.data, trunk->store.ptr, _send.info.len); //package end if (trunk->next == NULL) { _send.info.type = SW_EVENT_PACKAGE_END; } ret = factory->dispatch(factory, &_send); //TODO: 处理数据失败,数据将丢失 if (ret < 0) { swWarn("factory->dispatch failed."); } swBuffer_pop_trunk(buffer, trunk); trunk = swBuffer_get_trunk(buffer); swTrace("send2worker[trunk_num=%d][type=%d]\n", buffer->trunk_num, _send.info.type); } /** * unlock */ SwooleTG.factory_target_worker = -1; SwooleTG.factory_lock_target = 0; #endif return SW_OK; }