mirror of
https://github.com/openharmony/third_party_rust_libloading.git
synced 2026-07-19 21:23:39 -04:00
Drop the code for supporting XP/Vista
This commit is contained in:
@@ -16,7 +16,6 @@ categories = ["api-bindings"]
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = [
|
||||
"winerror",
|
||||
"errhandlingapi",
|
||||
"libloaderapi",
|
||||
]
|
||||
|
||||
@@ -25,6 +25,13 @@
|
||||
/// neither `RTLD_LOCAL` nor [`RTLD_GLOBAL`] are specified. Setting the `RTLD_LOCAL` flag makes
|
||||
/// the behaviour more consistent across platforms.
|
||||
///
|
||||
/// ### Dropped support for Windows XP/Vista
|
||||
///
|
||||
/// The (broken) support for Windows XP and Windows Vista environments was removed. This was
|
||||
/// prompted primarily by a similar policy change in the [Rust
|
||||
/// project](https://github.com/rust-lang/compiler-team/issues/378) but also as an acknowledgement
|
||||
/// to the fact that `libloading` never worked in these environments anyway.
|
||||
///
|
||||
/// [issue #86]: https://github.com/nagisa/rust_libloading/issues/86
|
||||
/// [`Library::new`]: crate::Library::new
|
||||
/// [windows_open]: crate::os::windows::Library::load_with_flags
|
||||
|
||||
+12
-44
@@ -28,7 +28,6 @@ mod windows_imports {
|
||||
extern crate winapi;
|
||||
pub(super) use self::winapi::shared::minwindef::{WORD, DWORD, HMODULE, FARPROC};
|
||||
pub(super) use self::winapi::shared::ntdef::WCHAR;
|
||||
pub(super) use self::winapi::shared::winerror;
|
||||
pub(super) use self::winapi::um::{errhandlingapi, libloaderapi};
|
||||
pub(super) use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
||||
pub(super) const SEM_FAILCE: DWORD = 1;
|
||||
@@ -55,7 +54,6 @@ use self::windows_imports::*;
|
||||
use util::{ensure_compatible_types, cstr_cow_from_bytes};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::{fmt, io, marker, mem, ptr};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
/// A platform-specific counterpart of the cross-platform [`Library`](crate::Library).
|
||||
pub struct Library(HMODULE);
|
||||
@@ -373,49 +371,23 @@ impl<T> fmt::Debug for Symbol<T> {
|
||||
}
|
||||
}
|
||||
|
||||
static USE_ERRORMODE: AtomicBool = AtomicBool::new(false);
|
||||
struct ErrorModeGuard(DWORD);
|
||||
|
||||
impl ErrorModeGuard {
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
fn new() -> Option<ErrorModeGuard> {
|
||||
unsafe {
|
||||
if !USE_ERRORMODE.load(Ordering::Acquire) {
|
||||
let mut previous_mode = 0;
|
||||
let success = errhandlingapi::SetThreadErrorMode(SEM_FAILCE, &mut previous_mode) != 0;
|
||||
if !success && errhandlingapi::GetLastError() == winerror::ERROR_CALL_NOT_IMPLEMENTED {
|
||||
USE_ERRORMODE.store(true, Ordering::Release);
|
||||
} else if !success {
|
||||
// SetThreadErrorMode failed with some other error? How in the world is it
|
||||
// possible for what is essentially a simple variable swap to fail?
|
||||
// For now we just ignore the error -- the worst that can happen here is
|
||||
// the previous mode staying on and user seeing a dialog error on older Windows
|
||||
// machines.
|
||||
return None;
|
||||
} else if previous_mode == SEM_FAILCE {
|
||||
return None;
|
||||
} else {
|
||||
return Some(ErrorModeGuard(previous_mode));
|
||||
}
|
||||
}
|
||||
match errhandlingapi::SetErrorMode(SEM_FAILCE) {
|
||||
SEM_FAILCE => {
|
||||
// This is important to reduce racy-ness when this library is used on multiple
|
||||
// threads. In particular this helps with following race condition:
|
||||
//
|
||||
// T1: SetErrorMode(SEM_FAILCE)
|
||||
// T2: SetErrorMode(SEM_FAILCE)
|
||||
// T1: SetErrorMode(old_mode) # not SEM_FAILCE
|
||||
// T2: SetErrorMode(SEM_FAILCE) # restores to SEM_FAILCE on drop
|
||||
//
|
||||
// This is still somewhat racy in a sense that T1 might restore the error
|
||||
// mode before T2 finishes loading the library, but that is less of a
|
||||
// concern – it will only end up in end user seeing a dialog.
|
||||
//
|
||||
// Also, SetErrorMode itself is probably not an atomic operation.
|
||||
None
|
||||
}
|
||||
a => Some(ErrorModeGuard(a))
|
||||
let mut previous_mode = 0;
|
||||
if errhandlingapi::SetThreadErrorMode(SEM_FAILCE, &mut previous_mode) == 0 {
|
||||
// How in the world is it possible for what is essentially a simple variable swap
|
||||
// to fail? For now we just ignore the error -- the worst that can happen here is
|
||||
// the previous mode staying on and user seeing a dialog error on older Windows
|
||||
// machines.
|
||||
None
|
||||
} else if previous_mode == SEM_FAILCE {
|
||||
None
|
||||
} else {
|
||||
Some(ErrorModeGuard(previous_mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,11 +396,7 @@ impl ErrorModeGuard {
|
||||
impl Drop for ErrorModeGuard {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if !USE_ERRORMODE.load(Ordering::Relaxed) {
|
||||
errhandlingapi::SetThreadErrorMode(self.0, ptr::null_mut());
|
||||
} else {
|
||||
errhandlingapi::SetErrorMode(self.0);
|
||||
}
|
||||
errhandlingapi::SetThreadErrorMode(self.0, ptr::null_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user