pipewire_native_spa/interface/
system.rs

1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: Copyright (c) 2025 Asymptotic Inc.
3// SPDX-FileCopyrightText: Copyright (c) 2025 Arun Raghavan
4
5use std::{any::Any, os::fd::RawFd, pin::Pin};
6
7use crate::flags;
8
9use super::plugin::Interface;
10
11#[repr(C, packed(1))]
12pub struct PollEvent {
13    pub events: flags::Io,
14    pub data: u64,
15}
16
17pub fn result_or_error<T: num::Integer>(res: T) -> std::io::Result<T> {
18    if res >= num::zero() {
19        Ok(res)
20    } else {
21        Err(std::io::Error::last_os_error())
22    }
23}
24
25pub struct SystemImpl {
26    pub inner: Pin<Box<dyn Any>>,
27
28    /* read/write/ioctl */
29    pub read: fn(this: &SystemImpl, fd: RawFd, buf: &mut [u8]) -> std::io::Result<isize>,
30    pub write: fn(this: &SystemImpl, fd: RawFd, buf: &[u8]) -> std::io::Result<isize>,
31    pub ioctl: unsafe extern "C" fn(fd: RawFd, request: u64, ...) -> i32,
32    pub close: fn(this: &SystemImpl, fd: RawFd) -> std::io::Result<i32>,
33
34    /* clock */
35    pub clock_gettime: fn(
36        this: &SystemImpl,
37        clockid: libc::clockid_t,
38        value: &mut libc::timespec,
39    ) -> std::io::Result<i32>,
40    pub clock_getres: fn(
41        this: &SystemImpl,
42        clockid: libc::clockid_t,
43        res: &mut libc::timespec,
44    ) -> std::io::Result<i32>,
45
46    /* poll */
47    pub pollfd_create: fn(this: &SystemImpl, flags: flags::Fd) -> std::io::Result<i32>,
48    pub pollfd_add: fn(
49        this: &SystemImpl,
50        pfd: RawFd,
51        fd: RawFd,
52        events: flags::Io,
53        data: u64,
54    ) -> std::io::Result<i32>,
55    pub pollfd_mod: fn(
56        this: &SystemImpl,
57        pfd: RawFd,
58        fd: RawFd,
59        events: flags::Io,
60        data: u64,
61    ) -> std::io::Result<i32>,
62    pub pollfd_del: fn(this: &SystemImpl, pfd: RawFd, fd: RawFd) -> std::io::Result<i32>,
63    pub pollfd_wait: fn(
64        this: &SystemImpl,
65        pfd: RawFd,
66        events: &mut [PollEvent],
67        timeout: i32,
68    ) -> std::io::Result<i32>,
69
70    /* timers */
71    pub timerfd_create:
72        fn(this: &SystemImpl, clockid: i32, flags: flags::Fd) -> std::io::Result<i32>,
73    pub timerfd_settime: fn(
74        this: &SystemImpl,
75        fd: RawFd,
76        flags: flags::Fd,
77        new_value: &libc::itimerspec,
78        old_value: Option<&mut libc::itimerspec>,
79    ) -> std::io::Result<i32>,
80    pub timerfd_gettime:
81        fn(this: &SystemImpl, fd: RawFd, curr_value: &mut libc::itimerspec) -> std::io::Result<i32>,
82    pub timerfd_read: fn(this: &SystemImpl, fd: RawFd) -> std::io::Result<u64>,
83
84    /* events */
85    pub eventfd_create: fn(this: &SystemImpl, flags: flags::Fd) -> std::io::Result<i32>,
86    pub eventfd_write: fn(this: &SystemImpl, fd: RawFd, count: u64) -> std::io::Result<i32>,
87    pub eventfd_read: fn(this: &SystemImpl, fd: RawFd) -> std::io::Result<u64>,
88
89    /* signals */
90    pub signalfd_create:
91        fn(this: &SystemImpl, signal: u32, flags: flags::Fd) -> std::io::Result<i32>,
92    pub signalfd_read: fn(this: &SystemImpl, fd: RawFd) -> std::io::Result<u32>,
93}
94
95impl SystemImpl {
96    pub fn read(&self, fd: RawFd, buf: &mut [u8]) -> std::io::Result<isize> {
97        (self.read)(self, fd, buf)
98    }
99
100    pub fn write(&self, fd: RawFd, buf: &[u8]) -> std::io::Result<isize> {
101        (self.write)(self, fd, buf)
102    }
103
104    /* ioctl will need to be invoked directly because of varargs */
105
106    pub fn close(&self, fd: RawFd) -> std::io::Result<i32> {
107        (self.close)(self, fd)
108    }
109
110    pub fn clock_gettime(
111        &self,
112        clockid: libc::clockid_t,
113        value: &mut libc::timespec,
114    ) -> std::io::Result<i32> {
115        (self.clock_gettime)(self, clockid, value)
116    }
117
118    pub fn clock_getres(
119        &self,
120        clockid: libc::clockid_t,
121        res: &mut libc::timespec,
122    ) -> std::io::Result<i32> {
123        (self.clock_getres)(self, clockid, res)
124    }
125
126    pub fn pollfd_create(&self, flags: flags::Fd) -> std::io::Result<i32> {
127        (self.pollfd_create)(self, flags)
128    }
129
130    pub fn pollfd_add(
131        &self,
132        pfd: RawFd,
133        fd: RawFd,
134        events: flags::Io,
135        data: u64,
136    ) -> std::io::Result<i32> {
137        (self.pollfd_add)(self, pfd, fd, events, data)
138    }
139
140    pub fn pollfd_mod(
141        &self,
142        pfd: RawFd,
143        fd: RawFd,
144        events: flags::Io,
145        data: u64,
146    ) -> std::io::Result<i32> {
147        (self.pollfd_mod)(self, pfd, fd, events, data)
148    }
149
150    pub fn pollfd_del(&self, pfd: RawFd, fd: RawFd) -> std::io::Result<i32> {
151        (self.pollfd_del)(self, pfd, fd)
152    }
153
154    pub fn pollfd_wait(
155        &self,
156        pfd: RawFd,
157        events: &mut [PollEvent],
158        timeout: i32,
159    ) -> std::io::Result<i32> {
160        (self.pollfd_wait)(self, pfd, events, timeout)
161    }
162
163    pub fn timerfd_create(&self, clockid: i32, flags: flags::Fd) -> std::io::Result<i32> {
164        (self.timerfd_create)(self, clockid, flags)
165    }
166
167    pub fn timerfd_settime(
168        &self,
169        fd: RawFd,
170        flags: flags::Fd,
171        new_value: &libc::itimerspec,
172        old_value: Option<&mut libc::itimerspec>,
173    ) -> std::io::Result<i32> {
174        (self.timerfd_settime)(self, fd, flags, new_value, old_value)
175    }
176
177    pub fn timerfd_gettime(
178        &self,
179        fd: RawFd,
180        curr_value: &mut libc::itimerspec,
181    ) -> std::io::Result<i32> {
182        (self.timerfd_gettime)(self, fd, curr_value)
183    }
184
185    pub fn timerfd_read(&self, fd: RawFd) -> std::io::Result<u64> {
186        (self.timerfd_read)(self, fd)
187    }
188
189    pub fn eventfd_create(&self, flags: flags::Fd) -> std::io::Result<i32> {
190        (self.eventfd_create)(self, flags)
191    }
192
193    pub fn eventfd_write(&self, fd: RawFd, count: u64) -> std::io::Result<i32> {
194        (self.eventfd_write)(self, fd, count)
195    }
196
197    pub fn eventfd_read(&self, fd: RawFd) -> std::io::Result<u64> {
198        (self.eventfd_read)(self, fd)
199    }
200
201    pub fn signalfd_create(&self, signal: u32, flags: flags::Fd) -> std::io::Result<i32> {
202        (self.signalfd_create)(self, signal, flags)
203    }
204
205    pub fn signalfd_read(&self, fd: RawFd) -> std::io::Result<u32> {
206        (self.signalfd_read)(self, fd)
207    }
208}
209
210impl Interface for SystemImpl {
211    unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
212        crate::support::ffi::system::make_native(self)
213    }
214
215    unsafe fn free_native(system: *mut super::ffi::CInterface) {
216        crate::support::ffi::system::free_native(system)
217    }
218}
219
220unsafe impl Send for SystemImpl {}
221unsafe impl Sync for SystemImpl {}