erlang关闭一个socket进入死循环的bug修复过程

1、现象

游戏服务器与多个客户端建立连接,socket设置参数如下[binary, {packet, 4}, {active, 0}, {reuseaddr, true}, {nodelay, false}, {packet_size, 4096}, {delay_send, true}, {send_timeout, 5000}, {keepalive, true}, {exit_on_close, true}],其中绝大多数socket可以正常通信,一两个通信异常,表现为服务端无法发送消息。此时,查看socket宿主进程状态,进程的消息列表堆积,堆栈在prim_inet:close_pend_loop/2处死循环。

2、查找过程

从进程的堆栈来看,进程执行到了gen_tcp:close/1,进入关闭流程,gen_tcp:close/1调用inet:tcp_close/1,最后执行prim_inet:close/1,其中prim模块部分代码如下
close(S) when is_port(S) ->
    case subscribe(S, [subs_empty_out_q]) of
	{ok, [{subs_empty_out_q,N}]} when N > 0 ->
	    close_pend_loop(S, N);   %% wait for pending output to be sent
	_ ->
	    close_port(S)
    end.

close_pend_loop(S, N) ->
    receive
	{empty_out_q,S} ->
	    close_port(S)
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值