1use crate::{ok, sys, AsHandleRef, Handle, HandleBased, HandleRef, Status};
8
9#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
14#[repr(transparent)]
15pub struct Counter(Handle);
16impl_handle_based!(Counter);
17
18impl Counter {
19 pub fn create() -> Counter {
33 let options = 0;
34 let mut handle = 0;
35 let status = unsafe { sys::zx_counter_create(options, &mut handle) };
36 ok(status).expect(
37 "counter creation always succeeds except with OOM or when job policy denies it",
38 );
39 unsafe { Counter::from(Handle::from_raw(handle)) }
40 }
41
42 pub fn add(&self, value: i64) -> Result<(), Status> {
44 let status = unsafe { sys::zx_counter_add(self.raw_handle(), value) };
45 ok(status)
46 }
47
48 pub fn read(&self) -> Result<i64, Status> {
50 let mut value = 0;
51 let status = unsafe { sys::zx_counter_read(self.raw_handle(), &mut value) };
52 ok(status).map(|()| value)
53 }
54
55 pub fn write(&self, value: i64) -> Result<(), Status> {
57 let status = unsafe { sys::zx_counter_write(self.raw_handle(), value) };
58 ok(status)
59 }
60}
61
62#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn counter_create() {
71 let counter = Counter::create();
72 assert_eq!(counter.read().unwrap(), 0);
73 }
74
75 #[test]
76 fn counter_add() {
77 let counter = Counter::create();
78 assert_eq!(counter.read().unwrap(), 0);
79 assert!(counter.add(i64::max_value()).is_ok());
80 assert_eq!(counter.read().unwrap(), i64::max_value());
81 assert_eq!(counter.add(1), Err(Status::OUT_OF_RANGE));
82 }
83
84 #[test]
85 fn counter_read_write() {
86 let counter = Counter::create();
87 assert_eq!(counter.read().unwrap(), 0);
88 assert!(counter.write(i64::min_value()).is_ok());
89 assert_eq!(counter.read().unwrap(), i64::min_value());
90 }
91}