cloud_filter/root/
connect.rs

1use std::{
2    sync::{mpsc::Sender, Arc},
3    thread::{self, JoinHandle},
4    time::Duration,
5};
6
7use windows::Win32::Storage::CloudFilters::{CfDisconnectSyncRoot, CF_CONNECTION_KEY};
8
9use crate::filter::{Callbacks, RawConnectionKey};
10
11/// A handle to the current session for a given sync root.
12///
13/// [Connection] will disconnect when dropped. Note that this
14/// does **NOT** mean the sync root will be unregistered. To do so, call
15/// [SyncRootId::unregister][crate::root::SyncRootId::unregister].
16#[derive(Debug)]
17pub struct Connection<F> {
18    connection_key: RawConnectionKey,
19
20    cancel_token: Sender<()>,
21    join_handle: JoinHandle<()>,
22
23    _callbacks: Callbacks,
24    filter: Arc<F>,
25}
26
27// this struct could house many more windows api functions, although they all seem to do nothing
28// according to the threads on microsoft q&a
29impl<T> Connection<T> {
30    pub(crate) fn new(
31        connection_key: RawConnectionKey,
32        cancel_token: Sender<()>,
33        join_handle: JoinHandle<()>,
34        callbacks: Callbacks,
35        filter: Arc<T>,
36    ) -> Self {
37        Self {
38            connection_key,
39            cancel_token,
40            join_handle,
41            _callbacks: callbacks,
42            filter,
43        }
44    }
45
46    /// A raw connection key used to identify the connection.
47    pub fn connection_key(&self) -> RawConnectionKey {
48        self.connection_key
49    }
50
51    /// A reference to the inner [SyncFilter][crate::filter::SyncFilter] struct.
52    pub fn filter(&self) -> &T {
53        &self.filter
54    }
55}
56
57impl<T> Drop for Connection<T> {
58    fn drop(&mut self) {
59        unsafe { CfDisconnectSyncRoot(CF_CONNECTION_KEY(self.connection_key)) }.unwrap();
60
61        _ = self.cancel_token.send(());
62        while !self.join_handle.is_finished() {
63            thread::sleep(Duration::from_millis(150));
64        }
65    }
66}