调整 ezio 的 TCPConnection 状态事件
上上周的时候给 ezio 做了一个调整,稍微修改了一下 TCPConnection 对外暴露的几个状态变化的事件。
起因是在写 example/chat-client 的时候,因为主线程单独跑了一个事件循环从 stdin 中读取用户输入,所以 ChatClient 以及内部的 TCPClient 是跑在另外的工作线程上。
因为那个时候 TCPClient 之对外暴露了 connection 和 disconnection 的事件回调(这两个事件还统一成了一个 on_connection()),所以自然选择在 disconnection 的时候进行退出主循环的操作。
但是这个时候会出现:
- 主循环结束后立马析构
ChatClient,连同内部的TCPClient一起销毁。因为这部分代码跑在主线程上,所以不会和工作线程有任何 coordination。 TCPClient会在触发on_connection()来表明连接断开后会继续做一些内部清理工作;然而因为前面已经将TCPClient析构了,导致 UAF
而当时为了解决这个问题,采用的 workaround 时,ChatClient::OnConnection() 在发现连接断开后,通过 RunTaskAfter() 的方式延后执行 EventLoop::Quit()。
这个做法非常丑陋而且不可靠。