open62541/ua/
server.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::ptr::{self, NonNull};

use open62541_sys::{UA_Server, UA_Server_delete, UA_Server_newWithConfig};

use crate::{ua, Error};

/// Wrapper for [`UA_Server`] from [`open62541_sys`].
///
/// This owns the wrapped data type. When the wrapper is dropped, its inner value is cleaned up with
/// [`UA_Server_delete()`].
#[derive(Debug)]
pub struct Server(NonNull<UA_Server>);

// SAFETY: We know that the underlying `UA_Server` allows access from different threads, i.e. it may
// be dropped in a different thread from where it was created.
unsafe impl Send for Server {}

// SAFETY: The underlying `UA_Server` can be used from different threads concurrently, at least with
// _most_ methods (those marked `UA_THREADSAFE` and/or with explicit mutex locks inside).
unsafe impl Sync for Server {}

impl Server {
    /// Creates server from server config.
    ///
    /// This consumes the config object and makes the server the owner of all contained data therein
    /// (e.g. logging configuration and logger instance).
    pub(crate) fn new_with_config(config: ua::ServerConfig) -> Self {
        let mut config = config.into_raw();
        let inner = unsafe { UA_Server_newWithConfig(ptr::addr_of_mut!(config)) };
        // PANIC: The only possible errors here are out-of-memory.
        let inner = NonNull::new(inner).expect("create UA_Server");
        Self(inner)
    }

    /// Returns const pointer to value.
    ///
    /// # Safety
    ///
    /// The value is owned by `Self`. Ownership must not be given away, in whole or in parts. This
    /// may happen when `open62541` functions are called that take ownership of values by pointer.
    #[allow(dead_code)] // This is unused for now.
    #[must_use]
    pub(crate) const unsafe fn as_ptr(&self) -> *const UA_Server {
        self.0.as_ptr()
    }

    /// Returns mutable pointer to value.
    ///
    /// # Safety
    ///
    /// The value is owned by `Self`. Ownership must not be given away, in whole or in parts. This
    /// may happen when `open62541` functions are called that take ownership of values by pointer.
    #[must_use]
    pub(crate) unsafe fn as_mut_ptr(&mut self) -> *mut UA_Server {
        self.0.as_ptr()
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        log::debug!("Deleting server");

        let status_code = ua::StatusCode::new(unsafe {
            // SAFETY: We retain ownership of `self`.
            UA_Server_delete(self.as_mut_ptr())
        });
        if let Err(error) = Error::verify_good(&status_code) {
            log::warn!("Error while dropping server: {error}");
        }
    }
}