anchao commented on PR #21477:
URL: https://github.com/apache/nuttx/pull/21477#issuecomment-6675634622
> There seems to be a change of behavior compared to the previous version as
this patch breaks the following code we use in Modbus application:
>
> ```c
> int epollfd = epoll_create1(0);
>
> struct eserver eservers[state->nservers];
> for (int i = 0; i < state->nservers; i++) {
> eservers[i] = (struct eserver){
> .type = EWAITER_SERVER,
> .server = state->servers[i],
> };
> struct epoll_event ev = {
> .events = EPOLLIN | EPOLLHUP,
> .data.ptr = &eservers[i],
> };
> int ret = epoll_ctl(epollfd, EPOLL_CTL_ADD,
> modbus_server_pollfd(state->servers[i]), &ev);
> assert(ret == 0);
> }
>
> while (!halt || !*halt) {
> struct epoll_event rev;
> int ret = epoll_wait(epollfd, &rev, 1, timeout);
> ...
> ```
>
> doesn't return at all. The fd obtained by `modbus_server_pollfd` is a TCP
socket.
>
> If the same code is run with serial server (fd for `epoll` is created by
`eventfd(0,0)` and then `eventfd_write(s->efd, 42)` is called), then the
`epoll_wait` returns multiple times, not just once as before the patch.
@michallenc
Thanks for the report. I fixed the behavior regression.
The issue was that rearming a delivered level-triggered node could consume
the synchronous readiness notification generated during the driver poll setup
and enqueue the node again immediately.
This made eventfd report repeatedly after a single eventfd_write(), and
could also affect TCP socket rearming.
I updated the epoll rearm path to suppress the synchronous setup-time
notification while keeping the pollfd armed for future lower-half
notifications. So a delivered node is rearmed, but it will not be reported
again until a new driver notification occurs.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]