void swClient_free(swClient *cli) { assert(cli->socket->fd != 0); //remove from reactor if (!cli->socket->closed) { cli->close(cli); } if (cli->socket->out_buffer) { swBuffer_free(cli->socket->out_buffer); cli->socket->out_buffer = NULL; } if (cli->socket->in_buffer) { swBuffer_free(cli->socket->in_buffer); cli->socket->in_buffer = NULL; } bzero(cli->socket, sizeof(swConnection)); if (cli->async) { cli->socket->removed = 1; } else { sw_free(cli->socket); } }
int swReactor_close(swReactor *reactor, int fd) { swConnection *socket = swReactor_get(reactor, fd); if (socket->out_buffer) { swBuffer_free(socket->out_buffer); socket->out_buffer = NULL; } if (socket->in_buffer) { swBuffer_free(socket->in_buffer); socket->in_buffer = NULL; } #ifdef SW_USE_OPENSSL if (socket->ssl) { swSSL_close(socket); } #endif bzero(socket, sizeof(swConnection)); return close(fd); }
/** * close connection */ SWINLINE void swConnection_close(swServer *serv, int fd, int notify) { swConnection *conn = swServer_get_connection(serv, fd); swReactor *reactor; swEvent notify_ev; if(conn == NULL) { swWarn("[Master]connection not found. fd=%d|max_fd=%d", fd, swServer_get_maxfd(serv)); return; } conn->active = 0; int reactor_id = conn->from_id; swCloseQueue *queue = &serv->reactor_threads[reactor_id].close_queue; //将关闭的fd放入队列 queue->events[queue->num] = fd; //增加计数 queue->num ++; reactor = &(serv->reactor_threads[reactor_id].reactor); swTrace("Close Event.fd=%d|from=%d", fd, reactor_id); //释放缓存区占用的内存 if (serv->open_eof_check == 1) { if (conn->in_buffer != NULL) { swBuffer_free(conn->in_buffer); conn->in_buffer = NULL; } } else if (serv->open_length_check == 1) { if (conn->object != NULL) { swString_free(conn->object); } } if (conn->out_buffer != NULL) { swBuffer_free(conn->out_buffer); conn->out_buffer = NULL; } if (conn->in_buffer != NULL) { swBuffer_free(conn->in_buffer); conn->in_buffer = NULL; } //通知到worker进程 if (serv->onClose != NULL && notify == 1) { //通知worker进程 notify_ev.from_id = reactor_id; notify_ev.fd = fd; notify_ev.type = SW_EVENT_CLOSE; SwooleG.factory->notify(SwooleG.factory, ¬ify_ev); } //通知主进程 if (queue->num == SW_CLOSE_QLEN) { swReactorThread_close_queue(reactor, queue); } #ifdef SW_SOCKET_SET_LINGER struct linger linger; linger.l_onoff = 0; linger.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger)) == -1) { swWarn("setsockopt(SO_LINGER) failed. Error: %s[%d]", strerror(errno), errno); } #endif //关闭此连接,必须放在最前面,以保证线程安全 reactor->del(reactor, fd); }