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

[bug] Event activated by event_active on another thread may loss while event timeout #1530

Open
Elylhance opened this issue Dec 5, 2023 · 4 comments

Comments

@Elylhance
Copy link

Elylhance commented Dec 5, 2023

[debug] event_active: 0x9114280 (fd 19), res 4, callback 0x43f853
[debug] epoll_dispatch: epoll_wait reports 1
[debug] event_active: 0x90f0a40 (fd 10), res 2, callback 0x7f09a5fb4b20
[debug] event_del: 0x9114380 (fd 20), callback 0x43f853
[debug] timeout_process: event: 0x9114380, call 0x43f853
[debug] event_active: 0x9114380 (fd 20), res 1, callback 0x43f853
[debug] event_del: 0x9114400 (fd 21), callback 0x43f853
[debug] timeout_process: event: 0x9114400, call 0x43f853
[debug] event_active: 0x9114400 (fd 21), res 1, callback 0x43f853
[debug] event_del: 0x9114480 (fd 22), callback 0x43f853
[debug] timeout_process: event: 0x9114480, call 0x43f853
[debug] event_active: 0x9114480 (fd 22), res 1, callback 0x43f853
[debug] event_del: 0x9114280 (fd 19), callback 0x43f853
[debug] timeout_process: event: 0x9114280, call 0x43f853
[debug] event_active: 0x9114280 (fd 19), res 1, callback 0x43f853
[debug] event_process_active: event: 0x90f0a40, EV_READ   call 0x7f09a5fb4b20
[debug] event_process_active: event: 0x9114380,    call 0x43f853
[debug] event_add: event: 0x9114380 (fd 20),   EV_CLOSED EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114380, timeout in 347343 seconds 593298 useconds, call 0x43f853
[debug] event_active: 0x9114380 (fd 20), res 4, callback 0x43f853
[debug] event_del: 0x9114380 (fd 20), callback 0x43f853
[debug] event_add: event: 0x9114380 (fd 20), EV_READ   EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114380, timeout in 86400 seconds 0 useconds, call 0x43f853
[debug] event_active: 0x9114380 (fd 20), res 4, callback 0x43f853
[debug] event_process_active: event: 0x9114400,    call 0x43f853
[debug] event_add: event: 0x9114400 (fd 21),   EV_CLOSED EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114400, timeout in 347343 seconds 593298 useconds, call 0x43f853
[debug] event_del: 0x9114400 (fd 21), callback 0x43f853
[debug] event_add: event: 0x9114400 (fd 21), EV_READ   EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114400, timeout in 86400 seconds 0 useconds, call 0x43f853
[debug] event_process_active: event: 0x9114480,    call 0x43f853
[debug] event_add: event: 0x9114480 (fd 22),   EV_CLOSED EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114480, timeout in 347343 seconds 593298 useconds, call 0x43f853
[debug] event_del: 0x9114480 (fd 22), callback 0x43f853
[debug] event_add: event: 0x9114480 (fd 22), EV_READ   EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114480, timeout in 86400 seconds 0 useconds, call 0x43f853
[debug] event_process_active: event: 0x9114280,    call 0x43f853
[debug] event_add: event: 0x9114280 (fd 19),   EV_CLOSED EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114280, timeout in 347343 seconds 593298 useconds, call 0x43f853
[debug] event_del: 0x9114280 (fd 19), callback 0x43f853
[debug] event_add: event: 0x9114280 (fd 19), EV_READ   EV_TIMEOUT call 0x43f853
[debug] event_add: event 0x9114280, timeout in 86400 seconds 0 useconds, call 0x43f853
--------------------------------------------------------------------------------------

the EV_WRITE event activated by event_active() on 0x9114280 loss

@Elylhance
Copy link
Author

/* Activate every event whose timeout has elapsed. */
static void
timeout_process(struct event_base *base)
{
	/* Caller must hold lock. */
	struct timeval now;
	struct event *ev;

	if (min_heap_empty_(&base->timeheap)) {
		return;
	}

	gettime(base, &now);

	while ((ev = min_heap_top_(&base->timeheap))) {
		if (evutil_timercmp(&ev->ev_timeout, &now, >))
			break;

		/* delete this event from the I/O queues */
		event_del_nolock_(ev, EVENT_DEL_NOBLOCK);          //<-- this line removed all active events

		event_debug(("timeout_process: event: %p, call %p",
			 ev, ev->ev_callback));
		event_active_nolock_(ev, EV_TIMEOUT, 1);
	}
}

@0xdddddddd
Copy link

/* Activate every event whose timeout has elapsed. */
static void
timeout_process(struct event_base *base)
{
	/* Caller must hold lock. */
	struct timeval now;
	struct event *ev;

	if (min_heap_empty_(&base->timeheap)) {
		return;
	}

	gettime(base, &now);

	while ((ev = min_heap_top_(&base->timeheap))) {
		if (evutil_timercmp(&ev->ev_timeout, &now, >))
			break;

		/* delete this event from the I/O queues */
		event_del_nolock_(ev, EVENT_DEL_NOBLOCK);          //<-- this line removed all active events

		event_debug(("timeout_process: event: %p, call %p",
			 ev, ev->ev_callback));
		event_active_nolock_(ev, EV_TIMEOUT, 1);
	}
}

If a timer is initialized, calling event_assign event_add two times in a row will cause the timer to expire!
will get stuck at the reference code

@azat
Copy link
Member

azat commented Feb 18, 2024

timeout_process works under lock, so any modifications to the event should be locked.

Have you enabled threads for event_base? evthread_use_pthreads

@Elylhance
Copy link
Author

yes. I call evthread_use_pthreads in the main thread first, then new event_base in worker threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants