Skip to main content

native_ipc/
memory.rs

1//! Common lifecycle and policy interface for the best native shared-memory backend.
2//!
3//! The region-to-prepared-to-batch path composed by [`crate::region`],
4//! [`crate::batch`], and [`crate::session`] is the supported transfer route;
5//! [`crate::memory::NativeRegion::prepare_for_sharing`] exists for the documented
6//! lower-level boundary directly on this module's own types and has no
7//! public transfer consumer.
8
9use core::fmt;
10use core::sync::atomic::{Ordering, compiler_fence};
11
12/// Native backend selected for the compilation target.
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub enum NativePlatform {
15    /// Linux sealed anonymous `memfd` mappings.
16    Linux,
17    /// macOS Mach VM memory-entry mappings.
18    MacOs,
19    /// Windows unnamed paging-file section mappings.
20    Windows,
21}
22
23/// Processor architecture selected for the native backend.
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum NativeArchitecture {
26    /// 64-bit Arm (Rust `aarch64`) architecture.
27    Arm64,
28    /// 64-bit x86 (Rust `x86_64`) architecture.
29    Amd64,
30}
31
32/// Kernel mechanism that freezes shared-memory authority before transfer.
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub enum AuthorityMechanism {
35    /// Linux descriptor seals plus a read-only imported mapping.
36    DescriptorSeals,
37    /// Mach memory-entry maximum protections.
38    MaximumPortRights,
39    /// Windows exact-rights duplicated section handles.
40    ExactHandleRights,
41}
42
43/// Cross-platform capabilities of the selected native backend.
44#[derive(Clone, Copy, Debug, Eq, PartialEq)]
45pub struct NativeMemoryCapabilities {
46    platform: NativePlatform,
47    architecture: NativeArchitecture,
48    authority: AuthorityMechanism,
49}
50
51impl NativeMemoryCapabilities {
52    /// Selected operating-system backend.
53    pub const fn platform(self) -> NativePlatform {
54        self.platform
55    }
56
57    /// Selected processor architecture.
58    pub const fn architecture(self) -> NativeArchitecture {
59        self.architecture
60    }
61
62    /// Native mechanism used to freeze or attenuate authority.
63    pub const fn authority_mechanism(self) -> AuthorityMechanism {
64        self.authority
65    }
66
67    /// Whether a private region can grow by allocating a replacement mapping.
68    pub const fn supports_replacement_growth(self) -> bool {
69        true
70    }
71
72    /// Whether a shared mapping can grow in place.
73    pub const fn supports_in_place_growth(self) -> bool {
74        false
75    }
76
77    /// Whether permission changes are accepted after sharing.
78    pub const fn supports_post_share_permission_changes(self) -> bool {
79        false
80    }
81
82    /// Whether dropping all owners automatically releases the anonymous object.
83    pub const fn releases_on_drop(self) -> bool {
84        true
85    }
86}
87
88/// Reports the native memory behavior selected for this target.
89pub const fn native_memory_capabilities() -> NativeMemoryCapabilities {
90    NativeMemoryCapabilities {
91        platform: native_platform(),
92        architecture: native_architecture(),
93        authority: authority_mechanism(),
94    }
95}
96
97/// Endpoint that will retain the sole writable mapping after transfer.
98#[derive(Clone, Copy, Debug, Eq, PartialEq)]
99pub enum WriterOwner {
100    /// The process creating and transferring the region remains the writer.
101    Creator,
102    /// The authenticated peer becomes the sole writer.
103    Peer,
104}
105
106/// Planned access for one endpoint after the sharing transition.
107#[derive(Clone, Copy, Debug, Eq, PartialEq)]
108pub enum MemoryAccess {
109    /// Mapping may load but cannot store.
110    ReadOnly,
111    /// Mapping is the sole store-capable view.
112    ReadWrite,
113}
114
115/// Exact creator/peer access requested for the future sharing transition.
116#[derive(Clone, Copy, Debug, Eq, PartialEq)]
117pub struct PermissionPlan {
118    writer: WriterOwner,
119}
120
121impl PermissionPlan {
122    /// Creates the only supported permission plan: one writer and one reader.
123    pub const fn new(writer: WriterOwner) -> Self {
124        Self { writer }
125    }
126
127    /// Endpoint selected as sole writer.
128    pub const fn writer(self) -> WriterOwner {
129        self.writer
130    }
131
132    /// Creator's access after authenticated transfer.
133    pub const fn creator_access(self) -> MemoryAccess {
134        match self.writer {
135            WriterOwner::Creator => MemoryAccess::ReadWrite,
136            WriterOwner::Peer => MemoryAccess::ReadOnly,
137        }
138    }
139
140    /// Peer's access after authenticated transfer.
141    pub const fn peer_access(self) -> MemoryAccess {
142        match self.writer {
143            WriterOwner::Creator => MemoryAccess::ReadOnly,
144            WriterOwner::Peer => MemoryAccess::ReadWrite,
145        }
146    }
147
148    /// Whether a mapping created by the library requests execute authority.
149    ///
150    /// This does not describe every alias a malicious native-capability holder
151    /// may create under the documented target-specific authority limits.
152    pub const fn library_view_executable(self) -> bool {
153        false
154    }
155}
156
157/// Capacity policy while a region is still private and quiescent.
158#[derive(Clone, Copy, Debug, Eq, PartialEq)]
159pub enum GrowthPolicy {
160    /// Mapping size is fixed at allocation.
161    Fixed,
162    /// Growth replaces the private mapping up to an inclusive logical limit.
163    ReplaceBeforeShare {
164        /// Maximum logical byte length.
165        maximum_len: usize,
166    },
167}
168
169/// Cleanup policy applied while the common wrapper still owns the region.
170#[derive(Clone, Copy, Debug, Eq, PartialEq)]
171pub enum CleanupPolicy {
172    /// Release the anonymous native object without an explicit clearing pass.
173    ReleaseOnDrop,
174    /// Clear the complete mapping before releasing it.
175    ClearThenRelease,
176}
177
178/// Mandatory authority-sealing policy for shared regions.
179#[derive(Clone, Copy, Debug, Eq, PartialEq)]
180pub enum SealPolicy {
181    /// Seal or attenuate native authority during the consuming share transition.
182    RequiredOnShare,
183}
184
185/// Immutable configuration for one native shared-memory region.
186#[derive(Clone, Copy, Debug, Eq, PartialEq)]
187pub struct RegionOptions {
188    logical_len: usize,
189    growth: GrowthPolicy,
190    cleanup: CleanupPolicy,
191    permissions: PermissionPlan,
192    seal: SealPolicy,
193}
194
195impl RegionOptions {
196    /// Creates a fixed-size region with clear-on-drop cleanup.
197    pub const fn fixed(logical_len: usize, writer: WriterOwner) -> Self {
198        Self {
199            logical_len,
200            growth: GrowthPolicy::Fixed,
201            cleanup: CleanupPolicy::ClearThenRelease,
202            permissions: PermissionPlan::new(writer),
203            seal: SealPolicy::RequiredOnShare,
204        }
205    }
206
207    /// Creates a private growable region with clear-on-drop cleanup.
208    ///
209    /// Growth allocates a replacement mapping. It is never available after
210    /// the region is consumed for native sharing.
211    pub const fn growable(logical_len: usize, maximum_len: usize, writer: WriterOwner) -> Self {
212        Self {
213            logical_len,
214            growth: GrowthPolicy::ReplaceBeforeShare { maximum_len },
215            cleanup: CleanupPolicy::ClearThenRelease,
216            permissions: PermissionPlan::new(writer),
217            seal: SealPolicy::RequiredOnShare,
218        }
219    }
220
221    /// Overrides cleanup behavior before the native sharing transition.
222    pub const fn with_cleanup(mut self, cleanup: CleanupPolicy) -> Self {
223        self.cleanup = cleanup;
224        self
225    }
226
227    /// Initial logical bytes requested by the caller.
228    pub const fn logical_len(self) -> usize {
229        self.logical_len
230    }
231
232    /// Private growth policy.
233    pub const fn growth(self) -> GrowthPolicy {
234        self.growth
235    }
236
237    /// Pre-transfer cleanup policy.
238    pub const fn cleanup(self) -> CleanupPolicy {
239        self.cleanup
240    }
241
242    /// Required one-writer permission plan.
243    pub const fn permissions(self) -> PermissionPlan {
244        self.permissions
245    }
246
247    /// Mandatory native authority-sealing behavior.
248    pub const fn seal(self) -> SealPolicy {
249        self.seal
250    }
251
252    /// Inclusive logical capacity limit.
253    pub const fn maximum_len(self) -> usize {
254        match self.growth {
255            GrowthPolicy::Fixed => self.logical_len,
256            GrowthPolicy::ReplaceBeforeShare { maximum_len } => maximum_len,
257        }
258    }
259}
260
261/// Current common lifecycle state.
262#[derive(Clone, Copy, Debug, Eq, PartialEq)]
263pub enum RegionState {
264    /// Region is private, writable, unshared, and not yet authority-sealed.
265    Quiescent,
266}
267
268/// Snapshot of a managed region's portable state and policy.
269#[derive(Clone, Copy, Debug, Eq, PartialEq)]
270pub struct RegionStatus {
271    /// Current lifecycle state.
272    pub state: RegionState,
273    /// Logical application-visible length.
274    pub logical_len: usize,
275    /// Native page-rounded mapping length.
276    pub mapped_len: usize,
277    /// Maximum pre-share logical length.
278    pub maximum_len: usize,
279    /// Whether another pre-share growth operation is possible.
280    pub can_grow: bool,
281    /// Future creator/peer permission assignment.
282    pub permissions: PermissionPlan,
283    /// Cleanup behavior while managed by this wrapper.
284    pub cleanup: CleanupPolicy,
285    /// Mandatory seal applied by the consuming native share transition.
286    pub seal: SealPolicy,
287}
288
289/// Portable allocation, policy, or lifecycle failure.
290#[derive(Debug)]
291pub enum MemoryError {
292    /// Shared-memory regions cannot be empty.
293    ZeroLength,
294    /// Configured maximum is smaller than the initial logical length.
295    MaximumBelowInitial {
296        /// Initial requested logical length.
297        initial: usize,
298        /// Configured maximum logical length.
299        maximum: usize,
300    },
301    /// Fixed-size policy rejects growth.
302    FixedSize,
303    /// Shrinking would silently discard user-owned bytes.
304    ShrinkUnsupported {
305        /// Current logical length.
306        current: usize,
307        /// Requested smaller logical length.
308        requested: usize,
309    },
310    /// Requested growth exceeds the configured limit.
311    MaximumExceeded {
312        /// Requested logical length.
313        requested: usize,
314        /// Configured maximum logical length.
315        maximum: usize,
316    },
317    /// Selected native backend rejected the bounded operation.
318    Platform {
319        /// Portable operation category.
320        operation: &'static str,
321    },
322    /// The operating-system CSPRNG could not mint object freshness.
323    RandomnessUnavailable,
324}
325
326impl fmt::Display for MemoryError {
327    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
328        write!(formatter, "native shared-memory operation failed: {self:?}")
329    }
330}
331
332impl std::error::Error for MemoryError {
333    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
334        None
335    }
336}
337
338#[cfg(target_os = "linux")]
339impl From<crate::backend::linux::LinuxError> for MemoryError {
340    fn from(_: crate::backend::linux::LinuxError) -> Self {
341        Self::Platform {
342            operation: "allocate",
343        }
344    }
345}
346
347#[cfg(target_os = "macos")]
348impl From<crate::backend::macos::MachError> for MemoryError {
349    fn from(_: crate::backend::macos::MachError) -> Self {
350        Self::Platform {
351            operation: "allocate",
352        }
353    }
354}
355
356#[cfg(target_os = "windows")]
357impl From<crate::backend::windows::WindowsError> for MemoryError {
358    fn from(_: crate::backend::windows::WindowsError) -> Self {
359        Self::Platform {
360            operation: "allocate",
361        }
362    }
363}
364
365/// Common owner of the best private native shared-memory object on this target.
366///
367/// It exposes logical initialization bytes only through a closure. Consuming
368/// [`NativeRegion::prepare_for_sharing`] hands the region to the existing
369/// authenticated platform transfer typestate, which applies real native seals
370/// and exact permissions. Growth and arbitrary permission changes are no longer
371/// possible after that transition.
372pub struct NativeRegion {
373    inner: Option<PlatformQuiescentRegion>,
374    logical_len: usize,
375    options: RegionOptions,
376}
377
378impl NativeRegion {
379    /// Allocates a zeroed anonymous region with a non-executable library view.
380    ///
381    /// Delegated native authority follows the documented target policy; on
382    /// Linux, a malicious memfd holder may create a separate executable alias.
383    pub fn allocate(options: RegionOptions) -> Result<Self, MemoryError> {
384        validate_options(options)?;
385        let inner = PlatformQuiescentRegion::new(options.logical_len())?;
386        Ok(Self {
387            inner: Some(inner),
388            logical_len: options.logical_len(),
389            options,
390        })
391    }
392
393    /// Returns the immutable allocation and authority policy.
394    pub const fn options(&self) -> RegionOptions {
395        self.options
396    }
397
398    /// Returns a portable status snapshot.
399    pub fn status(&self) -> RegionStatus {
400        let maximum_len = self.options.maximum_len();
401        RegionStatus {
402            state: RegionState::Quiescent,
403            logical_len: self.logical_len,
404            mapped_len: self.inner().len(),
405            maximum_len,
406            can_grow: matches!(
407                self.options.growth(),
408                GrowthPolicy::ReplaceBeforeShare { .. }
409            ) && self.logical_len < maximum_len,
410            permissions: self.options.permissions(),
411            cleanup: self.options.cleanup(),
412            seal: self.options.seal(),
413        }
414    }
415
416    /// Runs one initialization operation over logical bytes only.
417    ///
418    /// Page-rounded padding remains zero and inaccessible through this common
419    /// method. No capability has escaped while the closure runs.
420    pub fn initialize<R>(&mut self, operation: impl FnOnce(&mut [u8]) -> R) -> R {
421        let logical_len = self.logical_len;
422        operation(&mut self.inner_mut().as_bytes_mut()[..logical_len])
423    }
424
425    /// Clears the complete page-rounded mapping and retains it for reuse.
426    ///
427    /// Every byte, including native page padding, is overwritten through the
428    /// live mapping before this method returns.
429    pub fn clear(&mut self) {
430        clear_mapping(self.inner_mut());
431    }
432
433    /// Grows by replacing the still-private mapping and preserving logical bytes.
434    pub fn grow(&mut self, requested: usize) -> Result<(), MemoryError> {
435        if requested == 0 {
436            return Err(MemoryError::ZeroLength);
437        }
438        if requested < self.logical_len {
439            return Err(MemoryError::ShrinkUnsupported {
440                current: self.logical_len,
441                requested,
442            });
443        }
444        if requested == self.logical_len {
445            return Ok(());
446        }
447        let maximum = match self.options.growth() {
448            GrowthPolicy::Fixed => return Err(MemoryError::FixedSize),
449            GrowthPolicy::ReplaceBeforeShare { maximum_len } => maximum_len,
450        };
451        if requested > maximum {
452            return Err(MemoryError::MaximumExceeded { requested, maximum });
453        }
454
455        let mut replacement = PlatformQuiescentRegion::new(requested)?;
456        replacement.as_bytes_mut()[..self.logical_len]
457            .copy_from_slice(&self.inner().as_bytes()[..self.logical_len]);
458        let mut previous = self
459            .inner
460            .replace(replacement)
461            .expect("managed region always owns its mapping");
462        if self.options.cleanup() == CleanupPolicy::ClearThenRelease {
463            clear_mapping(&mut previous);
464        }
465        self.logical_len = requested;
466        Ok(())
467    }
468
469    /// Explicitly clears according to policy and releases the anonymous object.
470    pub fn close(mut self) {
471        self.release();
472    }
473
474    /// Overwrites the complete mapping, then explicitly releases it.
475    ///
476    /// This ignores [`CleanupPolicy`] and always performs the clearing pass.
477    /// It cannot erase copies previously made by a process, the kernel, or a
478    /// device. The region must still be quiescent and exclusively owned here;
479    /// shared regions are destroyed by their transferred lifecycle owner.
480    pub fn destroy(mut self) {
481        if let Some(inner) = self.inner.as_mut() {
482            clear_mapping(inner);
483        }
484        drop(self.inner.take());
485    }
486
487    /// Freezes initialization/growth and creates an opaque native share request.
488    ///
489    /// The private owner is consumed and cannot be reused after preparation.
490    ///
491    /// ```compile_fail
492    /// use native_ipc::memory::{NativeRegion, RegionOptions, WriterOwner};
493    /// let mut region = NativeRegion::allocate(RegionOptions::fixed(
494    ///     32,
495    ///     WriterOwner::Creator,
496    /// )).unwrap();
497    /// let _prepared = region.prepare_for_sharing().unwrap();
498    /// region.clear();
499    /// ```
500    pub fn prepare_for_sharing(mut self) -> Result<NativeShareRequest, MemoryError> {
501        let incarnation =
502            crate::backend::mint_incarnation().map_err(|()| MemoryError::RandomnessUnavailable)?;
503        Ok(NativeShareRequest {
504            inner: self.inner.take(),
505            incarnation,
506            logical_len: self.logical_len,
507            permissions: self.options.permissions(),
508            seal: self.options.seal(),
509            cleanup: self.options.cleanup(),
510        })
511    }
512
513    pub(crate) fn prepare_with_writer(
514        mut self,
515        writer: WriterOwner,
516    ) -> Result<NativeShareRequest, MemoryError> {
517        self.options.permissions = PermissionPlan::new(writer);
518        self.prepare_for_sharing()
519    }
520
521    fn inner(&self) -> &PlatformQuiescentRegion {
522        self.inner
523            .as_ref()
524            .expect("managed region always owns its mapping")
525    }
526
527    fn inner_mut(&mut self) -> &mut PlatformQuiescentRegion {
528        self.inner
529            .as_mut()
530            .expect("managed region always owns its mapping")
531    }
532
533    fn release(&mut self) {
534        if let Some(inner) = self.inner.as_mut()
535            && self.options.cleanup() == CleanupPolicy::ClearThenRelease
536        {
537            clear_mapping(inner);
538        }
539        drop(self.inner.take());
540    }
541}
542
543/// Consuming boundary between common memory management and native transfer.
544///
545/// This type exposes no bytes, native parts, or growth operation. It keeps the
546/// requested one-writer permission plan attached until a platform-neutral
547/// transfer batch consumes it.
548///
549/// ```compile_fail
550/// use native_ipc::memory::{NativeRegion, RegionOptions, WriterOwner};
551/// let region = NativeRegion::allocate(RegionOptions::fixed(
552///     32,
553///     WriterOwner::Creator,
554/// )).unwrap();
555/// let mut prepared = region.prepare_for_sharing().unwrap();
556/// prepared.initialize(|bytes| bytes.fill(0));
557/// ```
558pub struct NativeShareRequest {
559    inner: Option<PlatformQuiescentRegion>,
560    #[allow(dead_code)]
561    incarnation: [u8; 16],
562    logical_len: usize,
563    permissions: PermissionPlan,
564    seal: SealPolicy,
565    cleanup: CleanupPolicy,
566}
567
568impl NativeShareRequest {
569    /// Required creator/peer access assignment.
570    pub const fn permissions(&self) -> PermissionPlan {
571        self.permissions
572    }
573
574    /// Mandatory native authority-sealing policy.
575    pub const fn seal_policy(&self) -> SealPolicy {
576        self.seal
577    }
578
579    /// Complete native page-rounded mapping length.
580    pub fn mapped_len(&self) -> usize {
581        self.inner
582            .as_ref()
583            .expect("share request always owns its mapping")
584            .len()
585    }
586
587    #[allow(dead_code)]
588    pub(crate) const fn logical_len(&self) -> usize {
589        self.logical_len
590    }
591
592    #[allow(dead_code)]
593    pub(crate) const fn incarnation(&self) -> [u8; 16] {
594        self.incarnation
595    }
596
597    #[allow(dead_code)]
598    pub(crate) fn native_spec(&self, region_id: u128) -> Option<crate::protocol::NativeRegionSpec> {
599        crate::protocol::NativeRegionSpec::new(
600            region_id,
601            self.incarnation,
602            self.permissions.writer() as u32,
603            self.logical_len,
604            self.mapped_len(),
605        )
606    }
607
608    #[cfg(target_os = "linux")]
609    pub(crate) fn into_linux_quiescent(
610        mut self,
611    ) -> (crate::backend::linux::QuiescentRegion, CleanupPolicy) {
612        let inner = self
613            .inner
614            .take()
615            .expect("share request always owns its mapping");
616        (inner, self.cleanup)
617    }
618
619    #[cfg(target_os = "macos")]
620    pub(crate) fn into_macos_quiescent(
621        mut self,
622    ) -> (crate::backend::macos::QuiescentRegion, CleanupPolicy) {
623        let inner = self
624            .inner
625            .take()
626            .expect("share request always owns its mapping");
627        (inner, self.cleanup)
628    }
629
630    #[cfg(target_os = "windows")]
631    pub(crate) fn into_windows_quiescent(
632        mut self,
633    ) -> (crate::backend::windows::QuiescentRegion, CleanupPolicy) {
634        let inner = self
635            .inner
636            .take()
637            .expect("share request always owns its mapping");
638        (inner, self.cleanup)
639    }
640
641    /// Clears and releases a prepared request without sharing it.
642    pub fn destroy(mut self) {
643        if let Some(inner) = self.inner.as_mut() {
644            clear_mapping(inner);
645        }
646        drop(self.inner.take());
647    }
648
649    fn release(&mut self) {
650        if let Some(inner) = self.inner.as_mut()
651            && self.cleanup == CleanupPolicy::ClearThenRelease
652        {
653            clear_mapping(inner);
654        }
655        drop(self.inner.take());
656    }
657}
658
659impl Drop for NativeShareRequest {
660    fn drop(&mut self) {
661        self.release();
662    }
663}
664
665fn clear_mapping(region: &mut PlatformQuiescentRegion) {
666    for byte in region.as_bytes_mut() {
667        // SAFETY: the quiescent typestate uniquely owns the complete live
668        // mapping, and each byte pointer is valid for one volatile store.
669        unsafe { core::ptr::write_volatile(byte, 0) };
670    }
671    compiler_fence(Ordering::SeqCst);
672}
673
674impl Drop for NativeRegion {
675    fn drop(&mut self) {
676        self.release();
677    }
678}
679
680fn validate_options(options: RegionOptions) -> Result<(), MemoryError> {
681    if options.logical_len() == 0 {
682        return Err(MemoryError::ZeroLength);
683    }
684    let maximum = options.maximum_len();
685    if maximum < options.logical_len() {
686        return Err(MemoryError::MaximumBelowInitial {
687            initial: options.logical_len(),
688            maximum,
689        });
690    }
691    Ok(())
692}
693
694#[cfg(target_os = "linux")]
695/// Native quiescent region selected on Linux.
696pub(crate) type PlatformQuiescentRegion = crate::backend::linux::QuiescentRegion;
697#[cfg(target_os = "macos")]
698/// Native quiescent region selected on macOS.
699pub(crate) type PlatformQuiescentRegion = crate::backend::macos::QuiescentRegion;
700
701#[cfg(target_os = "windows")]
702/// Native quiescent region selected on Windows.
703pub(crate) type PlatformQuiescentRegion = crate::backend::windows::QuiescentRegion;
704#[cfg(target_os = "linux")]
705const fn native_platform() -> NativePlatform {
706    NativePlatform::Linux
707}
708#[cfg(target_os = "macos")]
709const fn native_platform() -> NativePlatform {
710    NativePlatform::MacOs
711}
712#[cfg(target_os = "windows")]
713const fn native_platform() -> NativePlatform {
714    NativePlatform::Windows
715}
716
717#[cfg(target_arch = "aarch64")]
718const fn native_architecture() -> NativeArchitecture {
719    NativeArchitecture::Arm64
720}
721
722#[cfg(target_arch = "x86_64")]
723const fn native_architecture() -> NativeArchitecture {
724    NativeArchitecture::Amd64
725}
726
727#[cfg(target_os = "linux")]
728const fn authority_mechanism() -> AuthorityMechanism {
729    AuthorityMechanism::DescriptorSeals
730}
731#[cfg(target_os = "macos")]
732const fn authority_mechanism() -> AuthorityMechanism {
733    AuthorityMechanism::MaximumPortRights
734}
735#[cfg(target_os = "windows")]
736const fn authority_mechanism() -> AuthorityMechanism {
737    AuthorityMechanism::ExactHandleRights
738}
739
740#[cfg(test)]
741#[path = "memory_test.rs"]
742mod tests;