zeromq / czmq

High-level C binding for ØMQ
czmq.zeromq.org
Mozilla Public License 2.0
1.16k stars 523 forks source link

zloop: ignore EINTR from poll if nonstop is enabled #2285

Closed oko256 closed 2 months ago

oko256 commented 3 months ago

If SIGINT signal arrives while poll is blocking, regardless of attached signal handler it will cause the poll to return with errno EINTR. Currently, this causes zloop to return from the event loop. For nonstop mode to work as intended, we have to ignore EINTR in this case.

Added test cases that verify the functionality when catching an actual SIGINT signal with and without nonstop mode. Tested in Linux and Windows.

Fixes #2284

oko256 commented 3 months ago

According to CI it seems like MacOS is not happy with the way I try to test this. I'll try to figure out why.

oko256 commented 2 months ago

The zloop macOS test issue was just too strict timing requirement on the test, so I relaxed those requirements a bit and now it passes nicely. The functionality itself was working just fine.

I also noticed that zsock tests have been failing apparently for some time on macOS, so I fixed that issue as well: other tests in zsock bind to 127.0.0.1:* but STREAM test was binding to *:* which didn't work on macOS and changing that fixed macOS tests as well.

sphaero commented 2 months ago

Thanks!

sphaero commented 2 weeks ago

I'm not sure but it might be handy to check whether the test runs in a debugger. As it raises sigint I don't think the signal handler will be run then.

oko256 commented 2 weeks ago

I'm not sure but it might be handy to check whether the test runs in a debugger. As it raises sigint I don't think the signal handler will be run then.

It is true that for example in gdb by default it will break into the debugger when SIGINT is raised and one needs to set handle SIGINT nostop pass in gdb before running to pass this test.

Since this behaviour depends on the internal behaviour of poll and how it reacts to signals (errno EINTR), I don't have better idea how to test this without actually raising a SIGINT. Maybe someone has a better idea? Or of course we can just remove this test completely if it's important to pass the tests in a debugger without any extra debugger settings?