]> git.proxmox.com Git - rustc.git/blobdiff - library/std/src/sys/unix/locks/pthread_condvar.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / std / src / sys / unix / locks / pthread_condvar.rs
index 099aa68706fa394f18855e8701b528ecf9478d01..78f10f0534c031f8079c7236e9cc1a4f8db72dd2 100644 (file)
@@ -1,12 +1,13 @@
 use crate::cell::UnsafeCell;
 use crate::sys::locks::{pthread_mutex, Mutex};
+use crate::sys_common::lazy_box::{LazyBox, LazyInit};
 use crate::time::Duration;
 
 pub struct Condvar {
     inner: UnsafeCell<libc::pthread_cond_t>,
 }
 
-pub type MovableCondvar = Box<Condvar>;
+pub(crate) type MovableCondvar = LazyBox<Condvar>;
 
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
@@ -18,6 +19,14 @@ fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
     if value > <libc::time_t>::MAX as u64 { <libc::time_t>::MAX } else { value as libc::time_t }
 }
 
+impl LazyInit for Condvar {
+    fn init() -> Box<Self> {
+        let mut condvar = Box::new(Self::new());
+        unsafe { condvar.init() };
+        condvar
+    }
+}
+
 impl Condvar {
     pub const fn new() -> Condvar {
         // Might be moved and address is changing it is better to avoid
@@ -32,14 +41,16 @@ impl Condvar {
         target_os = "android",
         target_os = "redox"
     ))]
-    pub unsafe fn init(&mut self) {}
+    unsafe fn init(&mut self) {}
 
     // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
     // So on that platform, init() should always be called
     // Moreover, that platform does not have pthread_condattr_setclock support,
     // hence that initialization should be skipped as well
-    #[cfg(target_os = "espidf")]
-    pub unsafe fn init(&mut self) {
+    //
+    // Similar story for the 3DS (horizon).
+    #[cfg(any(target_os = "espidf", target_os = "horizon"))]
+    unsafe fn init(&mut self) {
         let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null());
         assert_eq!(r, 0);
     }
@@ -50,9 +61,10 @@ impl Condvar {
         target_os = "l4re",
         target_os = "android",
         target_os = "redox",
-        target_os = "espidf"
+        target_os = "espidf",
+        target_os = "horizon"
     )))]
-    pub unsafe fn init(&mut self) {
+    unsafe fn init(&mut self) {
         use crate::mem::MaybeUninit;
         let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
         let r = libc::pthread_condattr_init(attr.as_mut_ptr());
@@ -91,7 +103,8 @@ impl Condvar {
         target_os = "macos",
         target_os = "ios",
         target_os = "android",
-        target_os = "espidf"
+        target_os = "espidf",
+        target_os = "horizon"
     )))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::mem;
@@ -123,7 +136,8 @@ impl Condvar {
         target_os = "macos",
         target_os = "ios",
         target_os = "android",
-        target_os = "espidf"
+        target_os = "espidf",
+        target_os = "horizon"
     ))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
         use crate::ptr;
@@ -179,14 +193,14 @@ impl Condvar {
 
     #[inline]
     #[cfg(not(target_os = "dragonfly"))]
-    pub unsafe fn destroy(&self) {
+    unsafe fn destroy(&mut self) {
         let r = libc::pthread_cond_destroy(self.inner.get());
         debug_assert_eq!(r, 0);
     }
 
     #[inline]
     #[cfg(target_os = "dragonfly")]
-    pub unsafe fn destroy(&self) {
+    unsafe fn destroy(&mut self) {
         let r = libc::pthread_cond_destroy(self.inner.get());
         // On DragonFly pthread_cond_destroy() returns EINVAL if called on
         // a condvar that was just initialized with
@@ -195,3 +209,10 @@ impl Condvar {
         debug_assert!(r == 0 || r == libc::EINVAL);
     }
 }
+
+impl Drop for Condvar {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe { self.destroy() };
+    }
+}