[Nut-upsdev] git stable, cppunit?
Greg Troxel
gdt at lexort.com
Mon Dec 2 14:35:06 GMT 2024
Progress! With "if EINTR, continue", the usual idiom for using select,
the tests run.
Then, I got:
$ ./cppunittest
D: Getting test suite...
D: Preparing test runner...
D: Setting test runner outputter...
D: Launching the test run...
.................................F.
nutipc_ut.cpp:259:Assertion
Test name: NutIPCUnitTest::testSignalRecvQuick
assertion failed
- Expression: caught_signals.size() == 5
Failures !!!
Run: 34 Failure total: 1 Failures: 1 Errors: 0
D: Got to the end of test suite with code 'false'
which is not a pass, but much better.
Running it under ktrace, it almost always passes.
However, the core premise of the test seems off. If there are multiple
kill calls with the same signal I'm 99% sure POSIX is fine with a single
entry into the handler if the signal from kill call#1 was not delivered
before the same signal was sent by call#2. signals are not messages;
they are a software version of hardware interrupts.
After a bunch of runs, I got a failure while being traced:
27766 27766 cppunittest 1733148881.022508648 CALL kill(0x6c76, SIGUSR1)
27766 27766 cppunittest 1733148881.022531398 RET kill 0
27766 27766 cppunittest 1733148881.022554065 CALL kill(0x6c76, SIGUSR2)
27766 27766 cppunittest 1733148881.022576731 RET kill 0
two signals sent rapidly
27766 24847 cppunittest 1733148881.022599356 RET __select50 -1 errno 4 Interrupted system call
Select bails out (before the handler is going to be invoked, I think).
This is only 91 us after the first kill is recorded in ktrace.
27766 27766 cppunittest 1733148881.022712606 CALL kill(0x6c76, SIGUSR2)
killer proc calls into kill again, only 200 us later. Perhaps it is
waiting for a lock, perhaps it determines that the signal is already
queued so there's nothing to do. It's legit for the OS to defer signal
delivery until the process being signaled gets scheduled, I think.
Can't be a long time, but I don't think you can complain about less than
a clock tick.
27766 24847 cppunittest 1733148881.022735272 PSIG SIGUSR1 caught handler=0x48556c mask=(): code=SI_USER sent by pid=27766, uid=10853)
27766 24847 cppunittest 1733148881.022791897 PSIG SIGUSR2 caught handler=0x48556c mask=(30): code=SI_USER sent by pid=27766, uid=10853)
two signals delivered
27766 27766 cppunittest 1733148881.022825939 RET kill 0
kill returns
27766 24847 cppunittest 1733148881.022837314 CALL write(6,0x7a94769ff558,8)
27766 27766 cppunittest 1733148881.022848647 CALL kill(0x6c76, SIGUSR1)
27766 24847 cppunittest 1733148881.022859939 GIO fd 6 wrote 8 bytes
"\^A\0\0\0\^_\0\0\0"
27766 27766 cppunittest 1733148881.022871272 RET kill 0
27766 24847 cppunittest 1733148881.022882647 RET write 8
27766 27766 cppunittest 1733148881.022893981 PSIG SIGUSR1 caught handler=0x48556c mask=(): code=SI_USER sent by pid=27766, uid=10853)
siguser1 sent to self?
27766 24847 cppunittest 1733148881.022905356 CALL setcontext(0x7a94769ff5f0)
27766 27766 cppunittest 1733148881.022916689 CALL write(6,0x7f7fffc945d8,8)
27766 24847 cppunittest 1733148881.022921689 RET setcontext JUSTRETURN
hacky patch, good enough to think about:
diff --git a/include/nutipc.hpp b/include/nutipc.hpp
index 56618d620..f6429dccd 100644
--- a/include/nutipc.hpp
+++ b/include/nutipc.hpp
@@ -607,6 +607,9 @@ void * Signal::HandlerThread<H>::main(void * comm_pipe_read_end) {
// TBD: Die or recover on error?
if (-1 == fdno) {
+ if (errno == EINTR)
+ continue;
+
std::stringstream e;
e << "Poll on communication pipe read end ";
More information about the Nut-upsdev
mailing list