libudev/
context.rs

1use ::handle::Handle;
2
3/// A libudev context. Contexts may not be sent or shared between threads. The `libudev(3)` manpage
4/// says:
5///
6/// > All functions require a libudev context to operate. This context can be create via
7/// > udev_new(3). It is used to track library state and link objects together. No global state is
8/// > used by libudev, everything is always linked to a udev context. Furthermore, multiple
9/// > different udev contexts can be used in parallel by multiple threads. However, a single
10/// > context must not be accessed by multiple threads in parallel.
11///
12/// In Rust, that means that `Context` is `!Send` and `!Sync`. This means a `Context` must be
13/// created in the thread where it will be used. Several contexts can exist in separate threads,
14/// but they can not be sent between threads.
15///
16/// Other types in this library (`Device`, `Enumerator`, `Monitor`, etc.) share a reference to a
17/// context, which means that these types must also be `!Send` and `!Sync`.
18pub struct Context {
19    udev: *mut ::ffi::udev,
20}
21
22impl Clone for Context {
23    /// Increments reference count of `libudev` context.
24    fn clone(&self) -> Self {
25        Context {
26            udev: unsafe { ::ffi::udev_ref(self.udev) },
27        }
28    }
29}
30
31impl Drop for Context {
32    /// Decrements reference count of `libudev` context.
33    fn drop(&mut self) {
34        unsafe {
35            ::ffi::udev_unref(self.udev);
36        }
37    }
38}
39
40#[doc(hidden)]
41impl Handle<::ffi::udev> for Context {
42    fn as_ptr(&self) -> *mut ::ffi::udev {
43        self.udev
44    }
45}
46
47impl Context {
48    /// Creates a new context.
49    pub fn new() -> ::Result<Self> {
50        Ok(Context {
51            udev: try_alloc!(unsafe { ::ffi::udev_new() }),
52        })
53    }
54}