void swTimeWheel_forward(swTimeWheel *tw, swReactor *reactor) { swHashMap *set = tw->wheel[tw->current]; tw->current = tw->current == tw->size - 1 ? 0 : tw->current + 1; swTraceLog(SW_TRACE_REACTOR, "current=%d.", tw->current); swConnection *conn; uint64_t fd; while (1) { conn = swHashMap_each_int(set, &fd); if (conn == NULL) { break; } conn->close_force = 1; conn->close_notify = 1; conn->close_wait = 1; conn->close_actively = 1; //notify to reactor thread if (conn->removed) { swReactorThread_close(reactor, (int) fd); } else { reactor->set(reactor, fd, SW_FD_TCP | SW_EVENT_WRITE); } } }
int swFactory_end(swFactory *factory, int fd) { swServer *serv = factory->ptr; swSendData _send; swDataHead info; bzero(&_send, sizeof(_send)); _send.info.fd = fd; _send.info.len = 0; _send.info.type = SW_EVENT_CLOSE; swConnection *conn = swWorker_get_connection(serv, fd); if (conn == NULL || conn->active == 0) { //swWarn("can not close. Connection[%d] not found.", _send.info.fd); return SW_ERR; } else if (conn->close_force) { goto do_close; } else if (conn->closing) { swWarn("The connection[%d] is closing.", fd); return SW_ERR; } else if (conn->closed) { return SW_ERR; } else { do_close: conn->closing = 1; if (serv->onClose != NULL) { info.fd = fd; info.from_id = conn->from_id; info.from_fd = conn->from_fd; serv->onClose(serv, &info); } conn->closing = 0; conn->closed = 1; conn->close_errno = 0; if (swBuffer_empty(conn->out_buffer)) { swReactor *reactor = &serv->reactor_threads[SwooleTG.id].reactor; return swReactorThread_close(reactor, conn->fd); } else { swBuffer_trunk *trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0); trunk->store.data.val1 = _send.info.type; return SW_OK; } } }