> Hi all, > > This change enhances the Java foreign functions and memory API to allow users > to inject thread-locals before a downcall. > > The lvalue `errno` is used for error handling in C. The C11 (draft) standard > gives the following use-case example: >> Thus, a program that uses errnofor error checking should set it to zero >> before a library function call, > then inspect it before a subsequent library function call. Of course, a > library function can save the > value of errno on entry and then set it to zero, as long as the original > value is restored if errno’s > value is still zero just before the return. > > In the present day, it is possible to retrieve `errno` by using the API > provided by `Linker.Option captureCallState`. This provides the Java-user a > memory segment for thread-local data, that is populated by the JVM. The > memory segment can be read using conventional FFM means, such as with a > `VarHandle`. > > However, the contents of this segment is not used to populate the thread > local data _before_ the downcall. As an example, in Java using the FFM API, > an end user calling `strtol` and checking for `ERANGE` would do the following > (in-line with the C standard footnote): set the captured call state buffer's > `errno` to zero, perform a downcall, and then read the captured call state > again to check if `errno` is still zero. While the memory segment sees > `errno=0`, this is not actually written to the thread before execution. Thus, > it is possible to observe stale or irrelevant error numbers. In this example, > one could observe `ENOENT` after the `strtol` call, which is incorrect > behaviour. > > This PR flushes the captured call state to the thread local variables before > the downcall, ensuring that procedures in accordance to the C standard are > possible. Since this was somewhat invasive, I ported it to non-Oracle > platforms as well. > > One thing worth noting is that the setting and retrieving of thread local > data is now coupled. Meaning, if a user wants to retrieve e.g. `errno` after > a downcall, it is their responsibility to ensure that `errno` is > appropriately set beforehand in order to make a meaningful comparison with > predetermined error ranges. > > Testing: tiers 1-4 on Linux (x64, AArch64), macOS (x64, AArch64) and Windows > (x64). I have built the JDK and run a [minimal but > representative](https://gist.github.com/Arraying/41db1b093dfa5cc4bc49f1213584d520) > test case on Oracle Linux 10 (x64) with Zero (native), s390x, powerpc64le > and riscv64 (all QEMU). I've smoke tested these platfo...
Paul Hübner has updated the pull request incrementally with one additional commit since the last revision: Reviewer feedback. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/30059/files - new: https://git.openjdk.org/jdk/pull/30059/files/9e48fa35..c630ebf2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=30059&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=30059&range=00-01 Stats: 20 lines in 2 files changed: 3 ins; 4 del; 13 mod Patch: https://git.openjdk.org/jdk/pull/30059.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/30059/head:pull/30059 PR: https://git.openjdk.org/jdk/pull/30059
