You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 44ba11a
Browse filesBrowse the repository at this point in the historyBrowse files
0.7.1 --- a bounded transfer waited upon the descriptor below the one it moved (#19)
`kal_timeout_read` and `kal_timeout_write` decoded their `kal_stream` argument
with `okl::unpack`, which is the decoder for an OWNED handle. A stream handle is
not one: `stream.cpp` states that these are this environment's own descriptors
and `kal_stream_read` and `kal_stream_write` take them as such.
THE DECODE DID NOT FAIL, WHICH IS WHY THE CALL SITE READ AS CORRECT. `handle.h`
packs an owned handle as `(generation << 32) | (fd + 1)`, so a bare descriptor N
has exactly the shape of a packed handle naming N-1, and `unpack` accepts it
whenever the generation recorded for N-1 is still zero. That is every index at
which no owned handle has yet been released. The wait was therefore performed
upon descriptor N-1 while the transfer that followed was performed upon N.
Measured with the packing arithmetic alone: `unpack(1) = 0`, `unpack(2) = 1`,
`unpack(5) = 4`. Of the three standard streams only `kal_stdin`, whose handle is
zero, fails to decode; `kal_stdout` decoded to descriptor 0 and `kal_stderr` to
1.
The former reading tested `unpack` and fell back when it failed, on the stated
ground that the standard streams are not packed. The ground is correct and the
conclusion drawn from it was not: no stream handle is packed here, so the
fallback was the path that should always have been taken.
WHAT A CALLER OBSERVED. Waiting upon a descriptor that never becomes ready is an
expiry, so a bounded read of a stream with bytes waiting reported
`kal_err_again`; waiting upon one that is ready lets the transfer proceed and
block, so an operation that states a bound could wait without one. Which of the
two occurred is a function of what happened to occupy the descriptor below, so
the same program answered differently run alone and run after something else,
and the index healed permanently once an owned handle at N-1 had been released.
Reported through openkal-musl in #13 as
`std::filesystem::copy_file` reporting `Resource temporarily unavailable` for
two ordinary files. libc++ opens the source with `O_NONBLOCK`, which is
meaningless for a regular file on a kernel and which openkal-musl routes through
this interface, so every byte of a file copy passed through the wait above.
`kal_timeout_accept` and `kal_timeout_recv_from` keep the decode and are
correct: a listener and a datagram are owned. The four call sites divide exactly
along the borrowed/owned line and the two that were wrong were the two holding a
borrowed handle.
--- the criterion -----------------------------------------------------------
`tests/conformance_v08.cpp` gains `timeout_stream_section`, and it is the first
section `main` runs. Nothing in this file reached the two operations before: the
existing observations are of an accept, whose handle is owned and was decoded
correctly, and of a zero-length write, which returns before it waits.
Sixteen channels rather than one, because under the defect the wait was upon
descriptor N-1 and whether that expires depends on what occupies N-1. First
rather than last, because the mistaken decode corrected itself for every index
at which an owned handle had already been released, so the same observation
placed after the listener and datagram sections would have held upon the defect.
Confirmed by putting the old implementation back:
0 of 16 bounded reads transferred
FAIL: a bounded read of a stream that has bytes waiting transfers them
conformance_v08 ... FAIL (exit 1, 0.04s)
and with this change, 7 suites passed, 0 failed.
`src/handle.h` records beside `unpack` that a word which was never packed is
accepted silently, and that a stream handle must not reach it.
Copy file name to clipboardExpand all lines: mcpp.toml
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
[package]
2
2
namespace = "mcpplibs"
3
3
name = "openkal-linux"
4
-
version = "0.7.0"
4
+
version = "0.7.1"
5
5
description = "The reference implementation of openkal for Linux, written on the kernel's own system-call interface so that it can be placed beneath a C library as well as above one."
0 commit comments