1 // Copyright 2018 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 #pragma once
6 
7 #include <lib/zx/fifo.h>
8 
9 #include <utility>
10 
11 namespace fzl {
12 
13 template<typename W, typename R = W>
14 class fifo {
15     static_assert(sizeof(W) == sizeof(R), "W and R must have the same size");
16 public:
17     constexpr fifo() = default;
18 
fifo(zx::fifo && fifo)19     explicit fifo(zx::fifo&& fifo) : fifo_(std::move(fifo)) {}
20 
fifo(zx_handle_t value)21     explicit fifo(zx_handle_t value) : fifo_(value) {}
22 
fifo(zx::handle && h)23     explicit fifo(zx::handle&& h) : fifo_(std::move(h)) {}
24 
25     void reset(zx_handle_t value = ZX_HANDLE_INVALID) {
26         fifo_.reset(value);
27     }
28 
get()29     const zx::fifo& get() const {
30         return fifo_;
31     }
32 
get_handle()33     zx_handle_t get_handle() const {
34         return fifo_.get();
35     }
36 
release()37     zx_handle_t release() {
38         return fifo_.release();
39     }
40 
replace(zx_rights_t rights,fifo * result)41     zx_status_t replace(zx_rights_t rights, fifo* result) {
42         return fifo_.replace(rights, &result->fifo_);
43     }
44 
wait_one(zx_signals_t signals,zx::time deadline,zx_signals_t * pending)45     zx_status_t wait_one(zx_signals_t signals, zx::time deadline,
46                          zx_signals_t* pending) const {
47         return fifo_.wait_one(signals, deadline, pending);
48     }
49 
signal(uint32_t clear_mask,uint32_t set_mask)50     zx_status_t signal(uint32_t clear_mask, uint32_t set_mask) const {
51         return fifo_.signal(clear_mask, set_mask);
52     }
53 
write(const W * buffer,size_t count,size_t * actual_count)54     zx_status_t write(const W* buffer, size_t count, size_t* actual_count) const {
55         return fifo_.write(sizeof(W), buffer, count, actual_count);
56     }
57 
write_one(const W & element)58     zx_status_t write_one(const W& element) const {
59         return fifo_.write(sizeof(W), &element, 1, nullptr);
60     }
61 
read(R * buffer,size_t count,size_t * actual_count)62     zx_status_t read(R* buffer, size_t count, size_t* actual_count) const {
63         return fifo_.read(sizeof(R), buffer, count, actual_count);
64     }
65 
read_one(R * element)66     zx_status_t read_one(R* element) const {
67         return fifo_.read(sizeof(R), element, 1, nullptr);
68     }
69 
70 private:
71     zx::fifo fifo_;
72 };
73 
74 template<typename W, typename R>
create_fifo(uint32_t elem_count,uint32_t options,fifo<W,R> * out0,fifo<R,W> * out1)75 zx_status_t create_fifo(uint32_t elem_count, uint32_t options, fifo<W, R>* out0, fifo<R, W>* out1) {
76     if (out0 == static_cast<void*>(out1)) {
77         return ZX_ERR_INVALID_ARGS;
78     }
79     zx_handle_t h0 = ZX_HANDLE_INVALID, h1 = ZX_HANDLE_INVALID;
80     zx_status_t result = zx_fifo_create(elem_count, sizeof(W), options, &h0, &h1);
81     out0->reset(h0);
82     out1->reset(h1);
83     return result;
84 }
85 
86 } // namespace fzl
87