diff --git a/Cargo.lock b/Cargo.lock index 6b4171439..5c9ff31b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -312,6 +312,7 @@ name = "event_monitor" version = "0.1.0" dependencies = [ "libc", + "once_cell", "serde", "serde_json", ] diff --git a/event_monitor/Cargo.toml b/event_monitor/Cargo.toml index 15ea36c89..35de894b7 100644 --- a/event_monitor/Cargo.toml +++ b/event_monitor/Cargo.toml @@ -6,5 +6,6 @@ edition = "2021" [dependencies] libc = "0.2.138" +once_cell = "1.16.0" serde = { version = "1.0.150", features = ["rc", "derive"] } serde_json = "1.0.89" diff --git a/event_monitor/src/lib.rs b/event_monitor/src/lib.rs index 20091f1d4..4e76d3bc8 100644 --- a/event_monitor/src/lib.rs +++ b/event_monitor/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // +use once_cell::sync::OnceCell; use serde::Serialize; use std::borrow::Cow; use std::collections::HashMap; @@ -11,12 +12,13 @@ use std::io::Write; use std::os::unix::io::AsRawFd; use std::time::{Duration, Instant}; -static mut MONITOR: Option<(File, Instant)> = None; +static MONITOR: OnceCell<(File, Instant)> = OnceCell::new(); /// This function must only be called once from the main process before any threads /// are created to avoid race conditions pub fn set_monitor(file: File) -> Result<(), std::io::Error> { - assert!(unsafe { MONITOR.is_none() }); + // There is only one caller of this function, so MONITOR is written to only once + assert!(MONITOR.get().is_none()); let fd = file.as_raw_fd(); let ret = unsafe { let mut flags = libc::fcntl(fd, libc::F_GETFL); @@ -26,9 +28,9 @@ pub fn set_monitor(file: File) -> Result<(), std::io::Error> { if ret < 0 { return Err(std::io::Error::last_os_error()); } - unsafe { - MONITOR = Some((file, Instant::now())); - }; + + MONITOR.get_or_init(|| (file, Instant::now())); + Ok(()) } @@ -41,7 +43,7 @@ struct Event<'a> { } pub fn event_log(source: &str, event: &str, properties: Option<&HashMap, Cow>>) { - if let Some((file, start)) = unsafe { MONITOR.as_ref() } { + if let Some((file, start)) = MONITOR.get().as_ref() { let e = Event { timestamp: start.elapsed(), source,