[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] a bug of libevent(2.1.4-alpha) IOCP: socket is closed twice when bufferevent is freed



I ran into a strange situation where some new connections were randomly closed just after many client connections were closed. I finally get the reason after diving into source code and debugging for several hours.

 

When bufferevent is freed, the internal socket is closed at be_async_ctrl().

Call stack:

>       51CY.exe!be_async_ctrl(bufferevent * bev, bufferevent_ctrl_op op, bufferevent_ctrl_data * data)  Line 673  C

       51CY.exe!bufferevent_cancel_all_(bufferevent * bev)  Line 884 + 0x15 bytes     C

       51CY.exe!bufferevent_free(bufferevent * bufev)  Line 786 + 0x9 bytes       C

       51CY.exe!be_filter_unlink(bufferevent * bev)  Line 234 + 0xf bytes     C

       51CY.exe!bufferevent_decref_and_unlock_(bufferevent * bufev)  Line 696 + 0xf bytes      C

       51CY.exe!bufferevent_free(bufferevent * bufev)  Line 787 + 0x9 bytes       C

 

Bufferevent_free() also forwards a event callback to event_base.

Call stack:

>       51CY.exe!event_callback_finalize_many_(event_base * base, int n_cbs, event_callback * * evcbs, void (event_callback *, void *)* cb)  Line 2210   C

       51CY.exe!bufferevent_decref_and_unlock_(bufferevent * bufev)  Line 713 + 0x18 bytes   C

       51CY.exe!bufferevent_free(bufferevent * bufev)  Line 787 + 0x9 bytes       C

 

The same socket is secondly closed when the event callback is invoked in the next event_base loop.

Callstack:

>       51CYClient.exe!evutil_closesocket(int sock)  Line 425 C

       51CYClient.exe!be_async_destruct(bufferevent * bev)  Line 386 + 0x9 bytes     C

       51CYClient.exe!bufferevent_finalize_cb_(event_callback * evcb, void * arg_)  Line 734 + 0xf bytes C

       51CYClient.exe!event_process_active_single_queue(event_base * base, evcallback_list * activeq, int max_to_process, const timeval * endtime)  Line 1604 + 0xe bytes  C

       51CYClient.exe!event_process_active(event_base * base)  Line 1668 + 0x14 bytes  C

       51CYClient.exe!event_base_loop(event_base * base, int flags)  Line 1890 + 0x9 bytes     C

 

So socket of new connection will be closed by this mean if the new socket handle value equals to the old one.