Struct kernel::grant::ProcessGrant
source · pub struct ProcessGrant<'a, T: 'a, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize> { /* private fields */ }
Expand description
An instance of a grant allocated for a particular process.
ProcessGrant
is a handle to an instance of a grant that has been
allocated in a specific process’s grant region. A ProcessGrant
guarantees that the memory for the grant has been allocated in the process’s
memory.
This is created from a Grant
when that grant is entered for a specific
process.
Implementations§
source§impl<'a, T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize> ProcessGrant<'a, T, Upcalls, AllowROs, AllowRWs>
impl<'a, T: Default, Upcalls: UpcallSize, AllowROs: AllowRoSize, AllowRWs: AllowRwSize> ProcessGrant<'a, T, Upcalls, AllowROs, AllowRWs>
sourcepub fn processid(&self) -> ProcessId
pub fn processid(&self) -> ProcessId
Return the ProcessId
of the process this ProcessGrant
is
associated with.
sourcepub fn enter<F, R>(self, fun: F) -> R
pub fn enter<F, R>(self, fun: F) -> R
Run a function with access to the memory in the related process for the related Grant. This also provides access to any associated Upcalls and allowed buffers stored with the grant.
This is “entering” the grant region, and the only time when the contents of a grant region can be accessed.
Note, a grant can only be entered once at a time. Attempting to call
.enter()
on a grant while it is already entered will result in a
panic!()
. See the comment in access_grant()
for more information.
sourcepub fn try_enter<F, R>(self, fun: F) -> Option<R>
pub fn try_enter<F, R>(self, fun: F) -> Option<R>
Run a function with access to the data in the related process for the related Grant only if that grant region is not already entered. If the grant is already entered silently skip it. Also provide access to associated Upcalls.
You almost certainly should use .enter()
rather than
.try_enter()
.
While the .enter()
version can panic, that panic likely indicates a
bug in the code and not a condition that should be handled. For example,
this benign looking code is wrong:
self.apps.enter(thisapp, |app_grant, _| {
// Update state in the grant region of `thisapp`. Also, mark that
// `thisapp` needs to run again.
app_grant.runnable = true;
// Now, check all apps to see if any are ready to run.
let mut work_left_to_do = false;
self.apps.iter().each(|other_app| {
other_app.enter(|other_app_grant, _| { // ERROR! This leads to a
if other_app_grant.runnable { // grant being entered
work_left_to_do = true; // twice!
}
})
})
})
The example is wrong because it tries to iterate across all grant regions while one of them is already entered. This will lead to a grant region being entered twice which violates Rust’s memory restrictions and is undefined behavior.
However, since the example uses .enter()
on the iteration, Tock will
panic when the grant is entered for the second time, notifying the
developer that something is wrong. The fix is to exit out of the first
.enter()
before attempting to iterate over the grant for all
processes.
However, if the example used .try_enter()
in the iter loop, there
would be no panic, but the already entered grant would be silently
skipped. This can hide subtle bugs if the skipped grant is only relevant
in certain cases.
Therefore, only use try_enter()
if you are sure you want to skip the
already entered grant. Cases for this are rare.
§Return
Returns None
if the grant is already entered. Otherwise returns
Some(fun())
.
sourcepub fn enter_with_allocator<F, R>(self, fun: F) -> R
pub fn enter_with_allocator<F, R>(self, fun: F) -> R
Run a function with access to the memory in the related process for the related Grant. Also provide this function with access to any associated Upcalls and an allocator for allocating additional memory in the process’s grant region.
This is “entering” the grant region, and the only time when the contents of a grant region can be accessed.
Note, a grant can only be entered once at a time. Attempting to call
.enter()
on a grant while it is already entered will result in a
panic!(). See the comment in
access_grant()` for more information.