]> git.proxmox.com Git - rustc.git/blame - src/vendor/magenta/src/fifo.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / vendor / magenta / src / fifo.rs
CommitLineData
ea8adc8c
XL
1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Type-safe bindings for Magenta fifo objects.
6
7use {HandleBase, Handle, HandleRef, Status};
8use {sys, into_result};
9
10/// An object representing a Magenta fifo.
11///
12/// As essentially a subtype of `Handle`, it can be freely interconverted.
13#[derive(Debug, Eq, PartialEq)]
14pub struct Fifo(Handle);
15
16impl HandleBase for Fifo {
17 fn get_ref(&self) -> HandleRef {
18 self.0.get_ref()
19 }
20
21 fn from_handle(handle: Handle) -> Self {
22 Fifo(handle)
23 }
24}
25
26impl Fifo {
27 /// Create a pair of fifos and return their endpoints. Writing to one endpoint enqueues an
28 /// element into the fifo from which the opposing endpoint reads. Wraps the
29 /// [mx_fifo_create](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/fifo_create.md)
30 /// syscall.
31 pub fn create(elem_count: u32, elem_size: u32, options: FifoOpts)
32 -> Result<(Fifo, Fifo), Status>
33 {
34 let mut out0 = 0;
35 let mut out1 = 0;
36 let status = unsafe {
37 sys::mx_fifo_create(elem_count, elem_size, options as u32, &mut out0, &mut out1)
38 };
39 into_result(status, || (Self::from_handle(Handle(out0)), Self::from_handle(Handle(out1))))
40 }
41
42 /// Attempts to write some number of elements into the fifo. The number of bytes written will be
43 /// rounded down to a multiple of the fifo's element size.
44 /// Return value (on success) is number of elements actually written.
45 ///
46 /// Wraps
47 /// [mx_fifo_write](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/fifo_write.md).
48 pub fn write(&self, bytes: &[u8]) -> Result<u32, Status> {
49 let mut num_entries_written = 0;
50 let status = unsafe {
51 sys::mx_fifo_write(self.raw_handle(), bytes.as_ptr(), bytes.len(),
52 &mut num_entries_written)
53 };
54 into_result(status, || num_entries_written)
55 }
56
57 /// Attempts to read some number of elements out of the fifo. The number of bytes read will
58 /// always be a multiple of the fifo's element size.
59 /// Return value (on success) is number of elements actually read.
60 ///
61 /// Wraps
62 /// [mx_fifo_read](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/fifo_read.md).
63 pub fn read(&self, bytes: &mut [u8]) -> Result<u32, Status> {
64 let mut num_entries_read = 0;
65 let status = unsafe {
66 sys::mx_fifo_read(self.raw_handle(), bytes.as_mut_ptr(), bytes.len(),
67 &mut num_entries_read)
68 };
69 into_result(status, || num_entries_read)
70 }
71}
72
73/// Options for creating a fifo pair.
74#[repr(u32)]
75#[derive(Debug, Copy, Clone, Eq, PartialEq)]
76pub enum FifoOpts {
77 /// Default options.
78 Default = 0,
79}
80
81impl Default for FifoOpts {
82 fn default() -> Self {
83 FifoOpts::Default
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn fifo_basic() {
93 let (fifo1, fifo2) = Fifo::create(4, 2, FifoOpts::Default).unwrap();
94
95 // Trying to write less than one element should fail.
96 assert_eq!(fifo1.write(b""), Err(Status::ErrOutOfRange));
97 assert_eq!(fifo1.write(b"h"), Err(Status::ErrOutOfRange));
98
99 // Should write one element "he" and ignore the last half-element as it rounds down.
100 assert_eq!(fifo1.write(b"hex").unwrap(), 1);
101
102 // Should write three elements "ll" "o " "wo" and drop the rest as it is full.
103 assert_eq!(fifo1.write(b"llo worlds").unwrap(), 3);
104
105 // Now that the fifo is full any further attempts to write should fail.
106 assert_eq!(fifo1.write(b"blah blah"), Err(Status::ErrShouldWait));
107
108 // Read all 4 entries from the other end.
109 let mut read_vec = vec![0; 8];
110 assert_eq!(fifo2.read(&mut read_vec).unwrap(), 4);
111 assert_eq!(read_vec, b"hello wo");
112
113 // Reading again should fail as the fifo is empty.
114 assert_eq!(fifo2.read(&mut read_vec), Err(Status::ErrShouldWait));
115 }
116}