Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
86a4b27
Increment `self.index` before calling `Iterator::self.a.__iterator_ge…
sdroege Feb 4, 2021
55ca27f
use rwlock for accessing ENV
the8472 Feb 6, 2021
406fd3a
silence dead code warnings on windows
the8472 Feb 7, 2021
c7d9bff
HWASan support
Jan 23, 2021
9c34c14
HWASan documentation
Feb 8, 2021
2200cf1
avoid &mut on the read path since it now allows concurrent readers
the8472 Feb 8, 2021
44abad5
introduce StaticRWLock wrapper to make methods safe
the8472 Feb 8, 2021
1d9ac3c
Fix const generics in GAT
BoxyUwU Feb 9, 2021
4fc181d
split guard into read and write types
the8472 Feb 9, 2021
2c4337a
Comments :3
BoxyUwU Feb 10, 2021
0422745
Fix comment smol mistakes
BoxyUwU Feb 10, 2021
0ffa2da
comma...
BoxyUwU Feb 10, 2021
d64b749
Allow casting mut array ref to mut ptr
osa1 Jan 28, 2021
7ca96ed
rewrite the comments
BoxyUwU Feb 10, 2021
02ffe9e
Fix injected errors when running doctests on a crate named after a ke…
jyn514 Dec 6, 2020
fda71d6
Push a `char` instead of a `str` with len one into a String
LingMan Feb 12, 2021
f546633
Remove unnecessary lint allow attrs on example
MikailBag Feb 12, 2021
de21cdf
update documents
VillSnow Jan 31, 2021
afdc8c7
stabilize partition_point
VillSnow Jan 14, 2021
fde59a8
Use `Iterator::all` instead of open-coding it
LingMan Feb 12, 2021
ab3f4f0
Rollup merge of #79775 - jyn514:doctest, r=GuillaumeGomez
Dylan-DPC Feb 12, 2021
8280abc
Rollup merge of #81012 - VillSnow:stabilize_partition_point, r=matklad
Dylan-DPC Feb 12, 2021
fc93e26
Rollup merge of #81479 - osa1:issue24151, r=lcnr
Dylan-DPC Feb 12, 2021
58d72ae
Rollup merge of #81506 - vo4:hwasan, r=nagisa
Dylan-DPC Feb 12, 2021
0cfba2f
Rollup merge of #81741 - sdroege:zip-trusted-random-access-specializa…
Dylan-DPC Feb 12, 2021
354f19c
Rollup merge of #81850 - the8472:env-rwlock, r=m-ou-se
Dylan-DPC Feb 12, 2021
b67be3a
Rollup merge of #81911 - BoxyUwU:constgenericgaticefix, r=nikomatsakis
Dylan-DPC Feb 12, 2021
ef7c45a
Rollup merge of #82022 - LingMan:single_char, r=jonas-schievink
Dylan-DPC Feb 12, 2021
54013fe
Rollup merge of #82023 - MikailBag:boxed-docs-unallow, r=jyn514
Dylan-DPC Feb 12, 2021
1ef566f
Rollup merge of #82030 - LingMan:init_directly, r=varkor
Dylan-DPC Feb 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
introduce StaticRWLock wrapper to make methods safe
  • Loading branch information
the8472 committed Feb 8, 2021
commit 44abad5b12afa58b9f495593f1c8b090e644fd7e
17 changes: 9 additions & 8 deletions library/std/src/sys/unix/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::str;
use crate::sys::cvt;
use crate::sys::fd;
use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
use crate::sys_common::rwlock::{RWLock, RWLockGuard};
use crate::sys_common::rwlock::{RWLockGuard, StaticRWLock};
use crate::vec;

use libc::{c_char, c_int, c_void};
Expand Down Expand Up @@ -494,16 +494,17 @@ pub unsafe fn environ() -> *mut *const *const c_char {
ptr::addr_of_mut!(environ)
}

pub unsafe fn env_rwlock(readonly: bool) -> RWLockGuard {
static ENV_LOCK: RWLock = RWLock::new();
if readonly { ENV_LOCK.read_with_guard() } else { ENV_LOCK.write_with_guard() }
static ENV_LOCK: StaticRWLock = StaticRWLock::new();

pub fn env_read_lock() -> RWLockGuard {
ENV_LOCK.read_with_guard()
}

/// Returns a vector of (variable, value) byte-vector pairs for all the
/// environment variables of the current process.
pub fn env() -> Env {
unsafe {
let _guard = env_rwlock(true);
let _guard = env_read_lock();
let mut environ = *environ();
let mut result = Vec::new();
if !environ.is_null() {
Expand Down Expand Up @@ -540,7 +541,7 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
// always None as well
let k = CString::new(k.as_bytes())?;
unsafe {
let _guard = env_rwlock(true);
let _guard = env_read_lock();
let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
let ret = if s.is_null() {
None
Expand All @@ -556,7 +557,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
let v = CString::new(v.as_bytes())?;

unsafe {
let _guard = env_rwlock(false);
let _guard = ENV_LOCK.write_with_guard();
cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
}
}
Expand All @@ -565,7 +566,7 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
let nbuf = CString::new(n.as_bytes())?;

unsafe {
let _guard = env_rwlock(false);
let _guard = ENV_LOCK.write_with_guard();
cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
}
}
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Command {
// a lock any more because the parent won't do anything and the child is
// in its own process.
let result = unsafe {
let _env_lock = sys::os::env_rwlock(true);
let _env_lock = sys::os::env_read_lock();
cvt(libc::fork())?
};

Expand Down Expand Up @@ -124,7 +124,7 @@ impl Command {
// Similar to when forking, we want to ensure that access to
// the environment is synchronized, so make sure to grab the
// environment lock before we try to exec.
let _lock = sys::os::env_rwlock(true);
let _lock = sys::os::env_read_lock();

let Err(e) = self.do_exec(theirs, envp.as_ref());
e
Expand Down Expand Up @@ -404,7 +404,7 @@ impl Command {
cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;

// Make sure we synchronize access to the global `environ` resource
let _env_lock = sys::os::env_rwlock(true);
let _env_lock = sys::os::env_read_lock();
let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::os::environ() as *const _);
cvt_nz(libc::posix_spawnp(
&mut p.pid,
Expand Down
109 changes: 60 additions & 49 deletions library/std/src/sys_common/rwlock.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
use crate::sys::rwlock as imp;

#[cfg(unix)]
enum GuardType {
Read,
Write,
}

#[cfg(unix)]
pub struct RWLockGuard(&'static RWLock, GuardType);

#[cfg(unix)]
impl Drop for RWLockGuard {
fn drop(&mut self) {
unsafe {
match &self.1 {
GuardType::Read => self.0.read_unlock(),
GuardType::Write => self.0.write_unlock(),
}
}
}
}

/// An OS-based reader-writer lock.
///
/// This structure is entirely unsafe and serves as the lowest layer of a
Expand All @@ -47,20 +26,6 @@ impl RWLock {
self.0.read()
}

/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
///
/// Behavior is undefined if the rwlock has been moved between this and any
/// previous method call.
#[inline]
#[cfg(unix)]
pub unsafe fn read_with_guard(&'static self) -> RWLockGuard {
self.read();
RWLockGuard(&self, GuardType::Read)
}

/// Attempts to acquire shared access to this lock, returning whether it
/// succeeded or not.
///
Expand All @@ -83,20 +48,6 @@ impl RWLock {
self.0.write()
}

/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
///
/// Behavior is undefined if the rwlock has been moved between this and any
/// previous method call.
#[inline]
#[cfg(unix)]
pub unsafe fn write_with_guard(&'static self) -> RWLockGuard {
self.write();
RWLockGuard(&self, GuardType::Write)
}

/// Attempts to acquire exclusive access to this lock, returning whether it
/// succeeded or not.
///
Expand Down Expand Up @@ -135,3 +86,63 @@ impl RWLock {
self.0.destroy()
}
}

// the cfg annotations only exist due to dead code warnings. the code itself is portable
#[cfg(unix)]
pub struct StaticRWLock(RWLock);

#[cfg(unix)]
impl StaticRWLock {
pub const fn new() -> StaticRWLock {
StaticRWLock(RWLock::new())
}

/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn read_with_guard(&'static self) -> RWLockGuard {
// Safety: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.read();
}
RWLockGuard(&self.0, GuardType::Read)
}

/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn write_with_guard(&'static self) -> RWLockGuard {
// Safety: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.write();
}
RWLockGuard(&self.0, GuardType::Write)
}
}

#[cfg(unix)]
enum GuardType {
Read,
Write,
}

#[cfg(unix)]
pub struct RWLockGuard(&'static RWLock, GuardType);

#[cfg(unix)]
impl Drop for RWLockGuard {
fn drop(&mut self) {
unsafe {
match &self.1 {
GuardType::Read => self.0.read_unlock(),
GuardType::Write => self.0.write_unlock(),
}
}
}
}