Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVENT_READING | EVENT_ERROR after bufferevent_enable but before bufferevent_socket_connect #1295

Closed
NeoProg2013 opened this issue Jul 8, 2022 · 8 comments

Comments

@NeoProg2013
Copy link

NeoProg2013 commented Jul 8, 2022

I have a simple TCP client.

Event loop working in thread #1 use event_base_loop(base, EVLOOP_ONCE).

TCP connection starting in thread #2:

  • Create socket socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  • call evutil_make_socket_nonblocking
  • Fill sockaddr_in strcture
  • call bufferevent_socket_new with BEV_OPT_THREADSAFE flag
  • call bufferevent_setcb with read and event callbacks. Write callback is NULL
  • call bufferevent_enable with EV_READ flag
    <------ Here libevent call my event callback with BEV_EVENT_READING | BEV_EVENT_ERROR
  • call bufferevent_socket_connect

Its normal behavior? I don't expect events before call bufferevent_socket_connect

@NeoProg2013 NeoProg2013 changed the title BEV_EVENT_READING | BEV_EVENT_ERROR after bufferevent_enable but before bufferevent_socket_connect EVENT_READING | EVENT_ERROR after bufferevent_enable but before bufferevent_socket_connect Jul 8, 2022
@azat
Copy link
Member

azat commented Jul 9, 2022

Its normal behavior? I don't expect events before call bufferevent_socket_connect

AFAICS it should not happen.
This sounds like a simple and reproducible issue.
Can you show a code sample?

@NeoProg2013
Copy link
Author

NeoProg2013 commented Jul 9, 2022

Oops. I can't reproduce it now. How i can enable max logging for libevent library without rebuild? When it starts again I will try to collect more information.
libevent-src.zip

@NeoProg2013
Copy link
Author

NeoProg2013 commented Jul 10, 2022

I reproduce it. Output from "libevent-src.zip"

Starting...
TCP port: 40487
Start event loop
Client thread is ready
call tcp_accept_connection_callback
call tcp_server_read_callback
call tcp_client_event_callback: 33
BEV_EVENT_ERROR
BEV_EVENT_READING
call tcp_client_event_callback: 128
BEV_EVENT_CONNECTED

Step by step:

  • Build example source code: g++ libevent-src.cpp -lpthread -levent -levent_core -levent_pthreads
  • Run binary
  • Connect to TCP port using telnet tool
  • Send any message
  • tcp_client_event_callback call twice

Reproducing is not 100%

@azat azat self-assigned this Jul 10, 2022
@azat
Copy link
Member

azat commented Jul 10, 2022

How i can enable max logging for libevent library without rebuild?

event_enable_debug_logging(EVENT_DBG_ALL)

libevent-src.zip

Thanks. You code has some issues, but this should not affect.

I reproduce it.

Can you provide strace log for such failure?
i.e. run program like this strace -s 1000 -f -tt -o strace.log /path/to/bin

And also separate output with event_enable_debug_logging(EVENT_DBG_ALL) but w/o strace.

@NeoProg2013
Copy link
Author

NeoProg2013 commented Jul 10, 2022

You code has some issues, but this should not affect.

Could you tell me more, please?

Can you provide strace log for such failure

Of course. I will let you know how the results are.

@NeoProg2013
Copy link
Author

NeoProg2013 commented Jul 11, 2022

I modified source code for fast reproduce -- each data read we starting new connection. After 3-4 times issue is reproduce.
libevent-update-1.zip

Problem signature in logs:

21128 12:11:17.231254 write(1, "call tcp_client_event_callback: 33\n", 35) = 35
21128 12:11:17.231437 write(1, "BEV_EVENT_ERROR\n", 16) = 16
21128 12:11:17.231607 write(1, "BEV_EVENT_READING\n", 18) = 18

strace.zip

stdout:
stdout.zip

Libevent version is 2.1.11-stable

@azat
Copy link
Member

azat commented Jul 11, 2022

Like I thought the problem that you've enabled EV_READ before connect, you should not do so, since you can read from unconnected socket.

@azat
Copy link
Member

azat commented Jul 11, 2022

Could you tell me more, please?

Sure.
Although maybe it is just a test sample and I should not be so critical.

Anyway here are some comments after a brief look:

Basic anti patterns:

  • you are using busy loops for waiting of the event
  • global variables

libevent anti patterns:

  • you are using separate thread for the event_base, it is better to have event_base per thread
  • you don't need to call evutil_make_socket_nonblocking() manually you can just pass -1 as fd and this will be done automatically
  • it is better to use EV_SIGNAL in programs that are using libevent, that way you will be able to use non-signal-safe functions in signal handlers, also note, that event_base_loopexit() is not signal safe

@azat azat closed this as completed Jul 11, 2022
@azat azat added the type:q label Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants