Closed zd-double closed 8 years ago
近期在线上出现RpcClient在退出时会hang住导致应用程序不能正常退出的现象
这种时序场景下,thread2新创建的连接被thread1误以为是关闭的连接移出_stream_map,该活动的连接无法在RpcClient析构时关掉,导致关联的io_service.run()不能返回,进而导致线程池阻塞。
在RpcClientImpl::OnClosed()删除关闭的连接时,进行一次判断:只有当stream状态为关闭才从_stream_map删除。实现见#109
赞
问题现象
近期在线上出现RpcClient在退出时会hang住导致应用程序不能正常退出的现象
问题原因
thread1 对失败的连接执行close() (rpc_byte_stream.h:66),第一步: 将该连接状态设为STATUS_CLOSED, 执行socket shutdown;
thread1 在close()第二步: 执行on_close()操作,首先将该连接上所有请求的回调依次执; thread2 在此时执行FindOrCreateStream,首先对_stream_map加锁;
thread1 执行on_closed()第二步:执行RpcClientImpl::OnClosed()的回调,对_stream_map加锁失败; thread2 此时已对_stream_map上锁,发现对应连接状态STATUS_CLOSED,重新创建连接,并插入_stream_map替掉之前的连接,完成后thread2 对_stream_map打开锁;
thread1对_stream_map加锁成功,删掉对应的连接,但此时连接已经是thread1新创建的连接; thread2 对新创建的连接异步connect;
这种时序场景下,thread2新创建的连接被thread1误以为是关闭的连接移出_stream_map,该活动的连接无法在RpcClient析构时关掉,导致关联的io_service.run()不能返回,进而导致线程池阻塞。
解决方案
在RpcClientImpl::OnClosed()删除关闭的连接时,进行一次判断:只有当stream状态为关闭才从_stream_map删除。实现见#109