[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re:Re: [Libevent-users] a bug of libevent(2.1.4-alpha) IOCP: socket is closed twice when bufferevent is freed
I verify the new codes with the patch, and the patch helps! Thank you!
At 2014-11-20 16:21:08, "Azat Khuzhin" <a3at.mail@xxxxxxxxx> wrote:
>On Thu, Nov 20, 2014 at 03:06:59PM +0800, jason wrote:
>> 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.
>
>Hi Jason,
>
>If I understand you correctly, the following patch must helps, could
>please verify this?
>
>diff --git a/bufferevent_async.c b/bufferevent_async.c
>index f32573e..6395e57 100644
>--- a/bufferevent_async.c
>+++ b/bufferevent_async.c
>@@ -381,9 +381,10 @@ be_async_destruct(struct bufferevent *bev)
> bev_async_del_write(bev_async);
>
> fd = evbuffer_overlapped_get_fd_(bev->input);
>- if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) {
>- /* XXXX possible double-close */
>+ if (fd != (evutil_socket_t)INVALID_SOCKET &&
>+ (bev_p->options & BEV_OPT_CLOSE_ON_FREE)) {
> evutil_closesocket(fd);
>+ evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
> }
> }
>
>@@ -671,6 +672,7 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
> if (fd != (evutil_socket_t)INVALID_SOCKET &&
> (bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) {
> closesocket(fd);
>+ evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
> }
> bev_a->ok = 0;
> return 0;
>
>(You email client could make patch un appliable I think, based on you
>incoming email, if so would happen, let me know, I will resend as an
>attachment).
>***********************************************************************
>To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
>unsubscribe libevent-users in the body.
N?§²æìr¸?zǧu©Þ?¨¥¶????Ý¢jç¡j÷§?ëp?Øn?Ë?±ÊâmébmëÞ?Û¬z»"?Ø^n?r