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