job: Add job mirroring

This commit is contained in:
Vicki Pfau 2024-06-27 20:51:53 -07:00
parent ae2351594f
commit 35eb5631ff

View file

@ -10,6 +10,7 @@ use libc::pid_t;
use nix::sys::signal; use nix::sys::signal;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
use nix::unistd::Pid; use nix::unistd::Pid;
use std::collections::HashMap;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::os::unix::process::ExitStatusExt; use std::os::unix::process::ExitStatusExt;
use std::process::ExitStatus; use std::process::ExitStatus;
@ -17,7 +18,8 @@ use tokio::process::{Child, Command};
use tracing::error; use tracing::error;
use zbus::{fdo, interface, zvariant, Connection, Interface, InterfaceRef, SignalContext}; use zbus::{fdo, interface, zvariant, Connection, Interface, InterfaceRef, SignalContext};
use crate::error::to_zbus_fdo_error; use crate::error::{to_zbus_fdo_error, zbus_to_zbus_fdo};
use crate::proxy::JobProxy;
const JOB_PREFIX: &str = "/com/steampowered/SteamOSManager1/Jobs"; const JOB_PREFIX: &str = "/com/steampowered/SteamOSManager1/Jobs";
@ -26,6 +28,7 @@ pub struct JobManager {
// keeps a handle to the zbus connection to expose the name over the bus. // keeps a handle to the zbus connection to expose the name over the bus.
connection: Connection, connection: Connection,
jm_iface: InterfaceRef<JobManagerInterface>, jm_iface: InterfaceRef<JobManagerInterface>,
mirrored_jobs: HashMap<String, zvariant::OwnedObjectPath>,
next_job: u32, next_job: u32,
} }
@ -37,6 +40,10 @@ struct Job {
struct JobManagerInterface {} struct JobManagerInterface {}
struct MirroredJob {
job: JobProxy<'static>,
}
impl JobManager { impl JobManager {
pub async fn new(connection: Connection) -> Result<JobManager> { pub async fn new(connection: Connection) -> Result<JobManager> {
let jm_iface = JobManagerInterface {}; let jm_iface = JobManagerInterface {};
@ -50,6 +57,7 @@ impl JobManager {
Ok(JobManager { Ok(JobManager {
connection, connection,
jm_iface, jm_iface,
mirrored_jobs: HashMap::new(),
next_job: 0, next_job: 0,
}) })
} }
@ -82,6 +90,33 @@ impl JobManager {
self.add_job(job).await self.add_job(job).await
} }
pub async fn mirror_job<'a, P>(
&mut self,
connection: &Connection,
path: P,
) -> fdo::Result<zvariant::OwnedObjectPath>
where
P: TryInto<zvariant::ObjectPath<'a>>,
P::Error: Into<zbus::Error>,
{
let path = path.try_into().map_err(Into::into)?.into_owned();
let name = format!("{}:{}", connection.server_guid(), path.as_str());
if let Some(object_path) = self.mirrored_jobs.get(&name) {
return Ok(object_path.clone());
}
let proxy = JobProxy::builder(connection)
.destination("com.steampowered.SteamOSManager1")?
.path(path)?
.build()
.await?;
let job = MirroredJob { job: proxy };
let object_path = self.add_job(job).await?;
self.mirrored_jobs.insert(name, object_path.to_owned());
Ok(object_path)
}
} }
#[interface(name = "com.steampowered.SteamOSManager1.JobManager")] #[interface(name = "com.steampowered.SteamOSManager1.JobManager")]
@ -203,6 +238,25 @@ impl Job {
} }
} }
#[interface(name = "com.steampowered.SteamOSManager1.Job")]
impl MirroredJob {
pub async fn pause(&mut self) -> fdo::Result<()> {
self.job.pause().await.map_err(zbus_to_zbus_fdo)
}
pub async fn resume(&mut self) -> fdo::Result<()> {
self.job.resume().await.map_err(zbus_to_zbus_fdo)
}
pub async fn cancel(&mut self, force: bool) -> fdo::Result<()> {
self.job.cancel(force).await.map_err(zbus_to_zbus_fdo)
}
pub async fn wait(&mut self) -> fdo::Result<i32> {
self.job.wait().await.map_err(zbus_to_zbus_fdo)
}
}
#[cfg(test)] #[cfg(test)]
pub(crate) mod test { pub(crate) mod test {
use super::*; use super::*;