mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-03-14 05:34:06 -04:00
Cancellation handlers use setjmp/longjmp, for which the C99 specification has the following note: > 17.3.2.1 (3) > All accessible objects have values, and all other components of the > abstract machine) have state, as of the time the longjmp function was > called, except that the values of objects of automatic storage > duration that are local to the function containing the invocation of > the corresponding setjmp macro that do not have volatile-qualified > type and have been changed between the setjmp invocation and longjmp > call are indeterminate. While everything works fine with GCC, with Clang we see that the cancellation handler doesn't seem to have an effect (loop-test fails when it notices that its spa_source's priv and mask have not been cleaned up). The underlying cause is that the compiler can assume data.ep_count is only used in loop_iterate_cancel(), and so can be cached in a register. When we access that field in the cancellation handler, it was never actually written to the memory on the stack, so the read in cancellation_handler() does not see the current value. We fix this by marking all fields on the stack that we expect to be modified in loop_iterate_cancel() as volatile, forcing the memory to be updated and correctly available to the cancellation handler. |
||
|---|---|---|
| .. | ||
| cpu-arm.c | ||
| cpu-riscv.c | ||
| cpu-x86.c | ||
| cpu.c | ||
| dbus.c | ||
| evl-plugin.c | ||
| evl-system.c | ||
| journal.c | ||
| logger.c | ||
| loop.c | ||
| meson.build | ||
| node-driver.c | ||
| null-audio-sink.c | ||
| plugin.c | ||
| system.c | ||