casaroli opened a new pull request, #21768:
URL: https://github.com/apache/nuttx/pull/21768

   depends-on: apache/nuttx/pull/21614
   depends-on: apache/nuttx/pull/21767
   depends-on: apache/nuttx/pull/21737
   
   ## Summary
   
   A datagram of a socket pair now goes into the FIFO as one atomic frame 
(`local_send_frame()`, `PIPEIOC_ATOMICWRITE`, from 6b50d0c8de4), and a stream 
send that waits now ends at a signal. This PR builds on #21614 and on #21767 
(its first two commits are those of #21767 until it merges). Its own commits:
   
   - net/local: Send a datagram of a socket pair as one frame. 
`local_pair_send()` (#21614) wrote the header and the data with two writes. A 
reader with `O_NONBLOCK` could get the header before the data, and then lost 
the boundaries of the next datagrams; a blocking send waited inside the 
datagram, so a signal could not end it. Now `local_socketpair()` puts the two 
datagram FIFOs in the atomic mode, and `local_pair_send()` sends with 
`local_send_frame()`, which gets the address of the sender as an argument (`""` 
for a pair, so `recvfrom()` gives no address, as before). The FIFO does not see 
`MSG_DONTWAIT`, so for this flag `local_pair_send()` still checks the space 
first.
   - net/local: Let a signal end a blocked send() of a stream socket. 
`local_fifo_write()` wrote again after `-EINTR` and after a short write, so a 
signal did not end `send()` or `write()` of a stream socket that waits for 
space. Now `local_send_packet()` calls `file_write()` once per segment and 
stops at an error or a short write: `-EINTR` before the first byte, else the 
bytes sent (POSIX). `local_fifo_write()` is removed.
   
   The datagram cases of signals during a send need no new pipe ioctl: the 
atomic frame waits for space for the whole frame before it copies, and a signal 
ends that wait with `EINTR`.
   
   ## Impact
   
   Local sockets only. The same code in flat, protected and kernel builds; no 
architecture code. What a program sees:
   
   - `send()`, `sendto()`, `sendmsg()` and `write()` of a datagram socket pair: 
a datagram goes whole or not at all, also for a reader with `O_NONBLOCK`; a 
signal ends a send that waits for space with `EINTR` (before, the send went on).
   - `send()` and `write()` of a stream socket that waits for space end at a 
signal: `EINTR` before any data, else the number of bytes sent. Also in a flat 
build (before, the call went on), and also with `SA_RESTART`, which NuttX does 
not implement. A signal whose default action ends the process now ends a 
process that waits in such a send.
   - Documentation: no page describes Unix domain sockets or the pipe ioctls; 
no change.
   
   ## Testing
   
   Tests: 8 new cases in `cmocka_net_local_dgram` (they follow in a nuttx-apps 
PR, on apache/nuttx-apps#4003): `poll_full`, `poll_fullwait`, `send_intr`, 
`pair_intr`, `stream_send_intr` (sends that wait for space; a signal during the 
wait), `pair_iov`, `send_iov` (`sendmsg()` of one datagram in 12 parts, two of 
them empty, on a pair and to a bound socket), `pair_whole` (a reader with 
`O_NONBLOCK` reads a full pair with no pause while a send waits in another 
thread: each datagram must come whole). All 8 pass on Linux (7.0, arm64 
container, host libc). Also the programs of #21614: `dgramabs`, `listenclose`, 
`peercred`, `dgrampair`, `sockintr` (signals, each case in a child) and 
`dgramconn`.
   
   qemu-armv8a (arm64, HVF, 1 CPU), make, apps #4003 with the apps PR, each 
case alone (`cmocka_net_local_dgram <dir> <case>`), a boot ends at a crash or a 
hang. knsh: kernel build, programs from `/system/bin`; nsh: flat build, 
builtins. Options: `NET`, `NET_IPv4`, `NET_LOOPBACK`, `NET_TCP`, `NET_UDP`, 
`NET_SOCKOPTS`, `NET_LOCAL` with stream, datagram and SCM, `PIPES`, `FS_TMPFS`, 
`DEBUG_ASSERTIONS`, `SIG_DEFAULT`, `SCHED_WAITPID`.
   
   | | #21614 (5eb6d40e7f8, on master 36cdd5ac3af) | this PR (with #21767) |
   |---|---|---|
   | `cmocka_net_local_dgram`, knsh and nsh | 87 of 91 PASS; FAIL: `pair_intr`, 
`stream_send_intr` (the send returns 100 after the reader made space, not -1 
`EINTR`), `send_iov` (`EMSGSIZE`), `pair_whole` (the reader gets a header 
without its data, then only -1 `EAGAIN`) | 91 PASS |
   | `cmocka_net_local` | knsh 6 PASS, nsh 4 PASS | knsh 6 PASS, nsh 4 PASS |
   | `sockintr` (19 cases) | knsh: 9 PASS, `stream-sendfull`, `stream-sendpart` 
FAIL, then `stream-sendterm` hangs (`SIGTERM` does not end the process); nsh: 
13 PASS, 6 FAIL (`stream-sendfull`, `stream-sendpart`, `dgram-sendclose`, 
`dgram-sendfull` and the 2 `SA_RESTART` cases) | knsh and nsh: 17 PASS; the 2 
`SA_RESTART` cases FAIL (NuttX has no `SA_RESTART`, also on #21614) |
   | `dgrampair`, `dgramconn`, `listenclose`, `peercred` (knsh) | 18, 21, 3, 5 
PASS | 18, 21, 3, 5 PASS |
   | `dgramabs` | knsh 11 PASS; nsh 10 PASS, `recvtcplong` FAIL (TCP, also on 
master) | the same |
   | ostest, knsh and nsh | status 0 | status 0 |
   
   `pair_iov` passes on #21614 too (it wrote the parts one by one); it covers 
the new copy path of `local_send_frame()`.
   
   Builds with `EXTRAFLAGS="-Wno-cpp -Werror"`, with `NET`, `NET_LOCAL`, 
`NETDEV_LATEINIT`, `NET_SOCKOPTS`, `PIPES`: qemu-armv8a:nsh (flat) with stream, 
datagram and `NET_LOCAL_SCM`, with datagram only and with stream only; 
mps2-an500:knsh (protected, armv7-m) and rv-virt:knsh64 (kernel, riscv64), each 
with stream, datagram and `NET_LOCAL_SCM`: all OK, no warning. Compilers: 
aarch64-none-elf GCC 14.2, arm-none-eabi GCC 15.3, riscv-none-elf GCC 14.3. 
Kconfig: qemu-armv8a:nsh with `NET_LOCAL_DGRAM` and `SERIAL` off has no 
`FS_UIO` on #21614, and `FS_UIO=y` with this PR.
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   
   Not run: CMake builds, sim, other compilers than GCC.
   


-- 
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]

Reply via email to