File dp_interrupt_guard_core.h¶
FileList > dp_interrupt_guard > dp_interrupt_guard_core.h
Go to the source code of this file
#include "dp_interrupt.h"#include <stddef.h>#include <stdint.h>
Public Types¶
| Type | Name |
|---|---|
| typedef dp_interrupt_guard_t | dp_interrupt_guard_state_t |
| typedef struct dp_interrupt_guard | dp_interrupt_guard_t A scoped handle to the process-wide interrupt facility. |
Public Functions¶
| Type | Name |
|---|---|
| dp_interrupt_guard_t * | dp_interrupt_guard_create (const int32_t * signals, size_t n_signals, uint32_t latency_ms) Clear the flag, optionally install handlers, and remember what to undo. |
| void | dp_interrupt_guard_destroy (dp_interrupt_guard_t * guard) Restore every handler and latency this guard changed. |
| void | dp_interrupt_guard_interrupt (dp_interrupt_guard_t * guard) Ask every blocking wait in this process to stop. |
| int | dp_interrupt_guard_interrupted (const dp_interrupt_guard_t * guard) Non-zero once a stop has been requested. |
| uint32_t | dp_interrupt_guard_latency_ms (const dp_interrupt_guard_t * guard) The wait slice every blocking wait in this process uses. |
| void | dp_interrupt_guard_resume (dp_interrupt_guard_t * guard) Clear the flag so waits proceed again. |
Public Types Documentation¶
typedef dp_interrupt_guard_state_t¶
typedef dp_interrupt_guard_t¶
A scoped handle to the process-wide interrupt facility.
The flag above is process-wide and stays so, so this is a handle to a facility rather than an instance of one: two guards observe the same flag. What a guard scopes is the arming which signals it installed, and the latency it overrode so that both can be undone exactly, by the code that did them, without a caller tracking it.
It exists because that bookkeeping had been living in the Python binding, which is the one place doppler does not put logic. See docs/design/io-termination.md.
Public Functions Documentation¶
function dp_interrupt_guard_create¶
Clear the flag, optionally install handlers, and remember what to undo.
dp_interrupt_guard_t * dp_interrupt_guard_create (
const int32_t * signals,
size_t n_signals,
uint32_t latency_ms
)
Construction is what ARMS: on return the handlers are installed and the flag is clear. A stale flag would otherwise refuse the first wait inside the very block that just armed it.
Parameters:
signalsSignals to install on; may be NULL for none, in which case the guard is only a handle to the flag.n_signalsHow manysignalsholds.latency_msWait-slice override; 0 leaves the process setting alone, and only a non-zero value is restored. Fixed width rather thanunsigned, because a public ABI should not carry a platform-dependent one.
Returns:
A guard, or NULL if a handler could not be installed in which case any already installed by this call are restored first, so a failed create arms nothing.
function dp_interrupt_guard_destroy¶
Restore every handler and latency this guard changed.
Does NOT clear the flag: a caller that was interrupted still needs to see that it was, after the block that noticed has exited.
Parameters:
guardGuard; NULL is a no-op.
function dp_interrupt_guard_interrupt¶
Ask every blocking wait in this process to stop.
The object's face onto dp_interrupt(). It takes a guard because that is how a method is called, not because the request is scoped to one the flag is process-wide, and a request through any guard is seen by every waiter.
Parameters:
guardGuard; NULL is a no-op.
>>> from doppler.interrupt import Interrupt
>>> it = Interrupt([])
>>> it.interrupt()
>>> it.interrupted()
1
function dp_interrupt_guard_interrupted¶
Non-zero once a stop has been requested.
Parameters:
guardGuard; NULL reads the flag anyway, since it is process-wide and a guard is not what holds it.
Returns:
Non-zero if interrupted.
>>> from doppler.interrupt import Interrupt
>>> import numpy as np
>>> it = Interrupt(np.array([], dtype=np.int32))
>>> it.interrupted()
0
>>> it.interrupt()
>>> it.interrupted()
1
function dp_interrupt_guard_latency_ms¶
The wait slice every blocking wait in this process uses.
The readback for the constructor's latency_ms, and it reads the PROCESS setting rather than what this guard asked for those differ when the guard passed 0, which means "leave it alone". A value a caller can set and not read back is a value they cannot reason about.
Parameters:
guardGuard; NULL reads the process setting anyway.
Returns:
Milliseconds.
>>> import numpy as np
>>> from doppler.interrupt import Interrupt
>>> it = Interrupt(np.array([], dtype=np.int32), latency_ms=25)
>>> it.latency_ms()
25
function dp_interrupt_guard_resume¶
Clear the flag so waits proceed again.
Parameters:
guardGuard; NULL is still honoured, for the reason above.
>>> from doppler.interrupt import Interrupt
>>> it = Interrupt([])
>>> it.interrupt()
>>> it.resume()
>>> it.interrupted()
0
The documentation for this class was generated from the following file native/inc/dp_interrupt_guard/dp_interrupt_guard_core.h