1- use std:: { collections:: HashMap , future:: pending, os:: unix:: net:: UnixStream } ;
1+ use std:: { collections:: HashMap , future:: pending, os:: unix:: net:: UnixStream , sync :: Arc } ;
22mod error;
33
44use ashpd:: {
@@ -9,29 +9,61 @@ use ashpd::{
99use clap:: Parser ;
1010pub use error:: Result ;
1111use oo7:: dbus:: Service ;
12- use tokio:: io:: AsyncWriteExt ;
12+ use tokio:: { io:: AsyncWriteExt , sync :: Mutex , task :: AbortHandle } ;
1313
1414const PORTAL_NAME : & str = "org.freedesktop.impl.portal.desktop.oo7" ;
1515
16- struct Secret ;
16+ #[ derive( Default ) ]
17+ struct Secret {
18+ active_requests : Arc < Mutex < HashMap < HandleToken , AbortHandle > > > ,
19+ }
1720
1821#[ async_trait:: async_trait]
1922impl ashpd:: backend:: request:: RequestImpl for Secret {
20- async fn close ( & self , _token : HandleToken ) { }
23+ async fn close ( & self , token : HandleToken ) {
24+ tracing:: debug!( "Closing request with token: {:?}" , token) ;
25+
26+ let mut requests = self . active_requests . lock ( ) . await ;
27+ if let Some ( abort_handle) = requests. remove ( & token) {
28+ tracing:: debug!( "Aborting active request for token: {:?}" , token) ;
29+ abort_handle. abort ( ) ;
30+ }
31+ }
2132}
2233
2334#[ async_trait:: async_trait]
2435impl ashpd:: backend:: secret:: SecretImpl for Secret {
2536 async fn retrieve (
2637 & self ,
27- _token : HandleToken ,
38+ token : HandleToken ,
2839 app_id : ashpd:: AppID ,
2940 fd : std:: os:: fd:: OwnedFd ,
3041 ) -> ashpd:: backend:: Result < HashMap < String , OwnedValue > > {
3142 tracing:: debug!( "Request from app: {app_id}" ) ;
32- send_secret_to_app ( & app_id, fd)
33- . await
43+
44+ let active_requests = self . active_requests . clone ( ) ;
45+ let task = tokio:: spawn ( async move {
46+ send_secret_to_app ( & app_id, fd) . await
47+ } ) ;
48+
49+ // Store the abort handle for this request
50+ {
51+ let mut requests = active_requests. lock ( ) . await ;
52+ requests. insert ( token. clone ( ) , task. abort_handle ( ) ) ;
53+ }
54+
55+ let result = task. await ;
56+
57+ // Remove the request from active requests once completed
58+ {
59+ let mut requests = active_requests. lock ( ) . await ;
60+ requests. remove ( & token) ;
61+ }
62+
63+ result
64+ . map_err ( |e| ashpd:: PortalError :: Failed ( format ! ( "Task failed: {e}" ) ) ) ?
3465 . map_err ( |e| ashpd:: PortalError :: Failed ( format ! ( "Could not retrieve secret {e}" ) ) ) ?;
66+
3567 Ok ( Default :: default ( ) )
3668 }
3769}
@@ -114,7 +146,7 @@ async fn main() -> Result<()> {
114146 }
115147
116148 ashpd:: backend:: Builder :: new ( PORTAL_NAME ) ?
117- . secret ( Secret )
149+ . secret ( Secret :: default ( ) )
118150 . with_flags ( flags)
119151 . build ( )
120152 . await
0 commit comments