Skip to content

Commit 5ab7762

Browse files
authored
Deprecate FutexOperation instead of futex (#1118)
With `rustix::thread::futex` being both a deprecated function and a public module, I'm seeing warnings like this when I use it in some simple testcases: ```console warning: use of deprecated function `rustix::thread::futex`: There are now individual functions available to perform futex operations with improved type safety. See the futex module. --> test.rs:2:21 | 2 | use rustix::thread::futex; | ^^^^^ | = note: `#[warn(deprecated)]` on by default ``` To fix this, move the deprecation from the `futex` function to the `FutexOperation` enum. This has the same effect, but doesn't produce the warning then the `futex` module is used. Also while using the API, I found `futex::FutexFlags` to be a little redundant, so I think it makes sense to rename it to `futex::Flags`, and similarly rename `futex::FUTEX_WAITERS` to `futex::WAITERS` and so on. This also splits `FutexOperation` into two enums internally, so that the public `FutexOperation` which is `#[non_exhausitive]` can continue to have its original contents, and the private enum can add new opcodes.
1 parent 4bd811f commit 5ab7762

File tree

8 files changed

+228
-230
lines changed

8 files changed

+228
-230
lines changed

src/backend/libc/thread/futex.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
use crate::backend::c;
22

33
bitflags::bitflags! {
4-
/// `FUTEX_*` flags for use with [`futex`].
4+
/// `FUTEX_*` flags for use with the functions in [`futex`].
55
///
66
/// [`futex`]: mod@crate::thread::futex
77
#[repr(transparent)]
88
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
9-
pub struct FutexFlags: u32 {
9+
pub struct Flags: u32 {
1010
/// `FUTEX_PRIVATE_FLAG`
1111
const PRIVATE = bitcast!(c::FUTEX_PRIVATE_FLAG);
1212
/// `FUTEX_CLOCK_REALTIME`
1313
const CLOCK_REALTIME = bitcast!(c::FUTEX_CLOCK_REALTIME);
1414
}
1515
}
1616

17-
/// `FUTEX_*` operations for use with [`futex`].
18-
///
19-
/// [`futex`]: mod@crate::thread::futex
17+
/// `FUTEX_*` operations for use with the futex syscall wrappers.
2018
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2119
#[repr(u32)]
22-
pub enum FutexOperation {
20+
pub(crate) enum Operation {
2321
/// `FUTEX_WAIT`
2422
Wait = bitcast!(c::FUTEX_WAIT),
2523
/// `FUTEX_WAKE`
@@ -50,8 +48,43 @@ pub enum FutexOperation {
5048
LockPi2 = bitcast!(c::FUTEX_LOCK_PI2),
5149
}
5250

51+
/// `FUTEX_*` operations for use with the [`futex`] function.
52+
///
53+
/// [`futex`]: fn@crate::thread::futex
54+
#[deprecated(
55+
since = "0.38.35",
56+
note = "
57+
The `futex` function and `FutexOperation` enum are deprecated. There are
58+
individual functions available to perform futex operations with improved
59+
type safety. See the `rustix::thread::futex` module."
60+
)]
61+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
62+
#[repr(u32)]
63+
pub enum FutexOperation {
64+
/// `FUTEX_WAIT`
65+
Wait = bitcast!(c::FUTEX_WAIT),
66+
/// `FUTEX_WAKE`
67+
Wake = bitcast!(c::FUTEX_WAKE),
68+
/// `FUTEX_FD`
69+
Fd = bitcast!(c::FUTEX_FD),
70+
/// `FUTEX_REQUEUE`
71+
Requeue = bitcast!(c::FUTEX_REQUEUE),
72+
/// `FUTEX_CMP_REQUEUE`
73+
CmpRequeue = bitcast!(c::FUTEX_CMP_REQUEUE),
74+
/// `FUTEX_WAKE_OP`
75+
WakeOp = bitcast!(c::FUTEX_WAKE_OP),
76+
/// `FUTEX_LOCK_PI`
77+
LockPi = bitcast!(c::FUTEX_LOCK_PI),
78+
/// `FUTEX_UNLOCK_PI`
79+
UnlockPi = bitcast!(c::FUTEX_UNLOCK_PI),
80+
/// `FUTEX_TRYLOCK_PI`
81+
TrylockPi = bitcast!(c::FUTEX_TRYLOCK_PI),
82+
/// `FUTEX_WAIT_BITSET`
83+
WaitBitset = bitcast!(c::FUTEX_WAIT_BITSET),
84+
}
85+
5386
/// `FUTEX_WAITERS`
54-
pub const FUTEX_WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS;
87+
pub const WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS;
5588

5689
/// `FUTEX_OWNER_DIED`
57-
pub const FUTEX_OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED;
90+
pub const OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED;

src/backend/libc/thread/syscalls.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ use core::mem::MaybeUninit;
1111
use core::sync::atomic::AtomicU32;
1212
#[cfg(linux_kernel)]
1313
use {
14-
super::futex::FutexOperation,
1514
crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize},
1615
crate::fd::BorrowedFd,
1716
crate::pid::Pid,
18-
crate::thread::FutexFlags,
17+
crate::thread::futex,
1918
crate::utils::as_mut_ptr,
2019
};
2120
#[cfg(not(any(
@@ -420,14 +419,14 @@ pub(crate) fn setresgid_thread(
420419
#[cfg(linux_kernel)]
421420
pub(crate) unsafe fn futex_val2(
422421
uaddr: *const AtomicU32,
423-
op: FutexOperation,
424-
flags: FutexFlags,
422+
op: super::futex::Operation,
423+
flags: futex::Flags,
425424
val: u32,
426425
val2: u32,
427426
uaddr2: *const AtomicU32,
428427
val3: u32,
429428
) -> io::Result<usize> {
430-
// the least significant four bytes of the timeout pointer are used as `val2`.
429+
// The least-significant four bytes of the timeout pointer are used as `val2`.
431430
// ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html),
432431
// so we perform that exact conversion in reverse to create the pointer.
433432
let timeout = val2 as usize as *const Timespec;
@@ -493,8 +492,8 @@ pub(crate) unsafe fn futex_val2(
493492
#[cfg(linux_kernel)]
494493
pub(crate) unsafe fn futex_timeout(
495494
uaddr: *const AtomicU32,
496-
op: FutexOperation,
497-
flags: FutexFlags,
495+
op: super::futex::Operation,
496+
flags: futex::Flags,
498497
val: u32,
499498
timeout: *const Timespec,
500499
uaddr2: *const AtomicU32,
@@ -574,8 +573,8 @@ pub(crate) unsafe fn futex_timeout(
574573
))]
575574
unsafe fn futex_old_timespec(
576575
uaddr: *const AtomicU32,
577-
op: FutexOperation,
578-
flags: FutexFlags,
576+
op: super::futex::Operation,
577+
flags: futex::Flags,
579578
val: u32,
580579
timeout: *const Timespec,
581580
uaddr2: *const AtomicU32,

src/backend/linux_raw/conv.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -792,15 +792,15 @@ impl<'a, Num: ArgNumber> From<(crate::net::SocketType, crate::net::SocketFlags)>
792792
#[cfg(feature = "thread")]
793793
impl<'a, Num: ArgNumber>
794794
From<(
795-
crate::backend::thread::futex::FutexOperation,
796-
crate::thread::FutexFlags,
795+
crate::backend::thread::futex::Operation,
796+
crate::thread::futex::Flags,
797797
)> for ArgReg<'a, Num>
798798
{
799799
#[inline]
800800
fn from(
801801
pair: (
802-
crate::backend::thread::futex::FutexOperation,
803-
crate::thread::FutexFlags,
802+
crate::backend::thread::futex::Operation,
803+
crate::thread::futex::Flags,
804804
),
805805
) -> Self {
806806
c_uint(pair.0 as u32 | pair.1.bits())

src/backend/linux_raw/thread/futex.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
bitflags::bitflags! {
2-
/// `FUTEX_*` flags for use with [`futex`].
2+
/// `FUTEX_*` flags for use with the functions in [`futex`].
33
///
44
/// [`futex`]: mod@crate::thread::futex
55
#[repr(transparent)]
66
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
7-
pub struct FutexFlags: u32 {
7+
pub struct Flags: u32 {
88
/// `FUTEX_PRIVATE_FLAG`
99
const PRIVATE = linux_raw_sys::general::FUTEX_PRIVATE_FLAG;
1010
/// `FUTEX_CLOCK_REALTIME`
@@ -16,12 +16,10 @@ bitflags::bitflags! {
1616
}
1717
}
1818

19-
/// `FUTEX_*` operations for use with [`futex`].
20-
///
21-
/// [`futex`]: mod@crate::thread::futex
19+
/// `FUTEX_*` operations for use with the futex syscall wrappers.
2220
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2321
#[repr(u32)]
24-
pub enum FutexOperation {
22+
pub(crate) enum Operation {
2523
/// `FUTEX_WAIT`
2624
Wait = linux_raw_sys::general::FUTEX_WAIT,
2725
/// `FUTEX_WAKE`
@@ -52,8 +50,43 @@ pub enum FutexOperation {
5250
LockPi2 = linux_raw_sys::general::FUTEX_LOCK_PI2,
5351
}
5452

53+
/// `FUTEX_*` operations for use with the [`futex`] function.
54+
///
55+
/// [`futex`]: fn@crate::thread::futex
56+
#[deprecated(
57+
since = "0.38.35",
58+
note = "
59+
The `futex` function and `FutexOperation` enum are deprecated. There are
60+
individual functions available to perform futex operations with improved
61+
type safety. See the `rustix::thread::futex` module."
62+
)]
63+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
64+
#[repr(u32)]
65+
pub enum FutexOperation {
66+
/// `FUTEX_WAIT`
67+
Wait = linux_raw_sys::general::FUTEX_WAIT,
68+
/// `FUTEX_WAKE`
69+
Wake = linux_raw_sys::general::FUTEX_WAKE,
70+
/// `FUTEX_FD`
71+
Fd = linux_raw_sys::general::FUTEX_FD,
72+
/// `FUTEX_REQUEUE`
73+
Requeue = linux_raw_sys::general::FUTEX_REQUEUE,
74+
/// `FUTEX_CMP_REQUEUE`
75+
CmpRequeue = linux_raw_sys::general::FUTEX_CMP_REQUEUE,
76+
/// `FUTEX_WAKE_OP`
77+
WakeOp = linux_raw_sys::general::FUTEX_WAKE_OP,
78+
/// `FUTEX_LOCK_PI`
79+
LockPi = linux_raw_sys::general::FUTEX_LOCK_PI,
80+
/// `FUTEX_UNLOCK_PI`
81+
UnlockPi = linux_raw_sys::general::FUTEX_UNLOCK_PI,
82+
/// `FUTEX_TRYLOCK_PI`
83+
TrylockPi = linux_raw_sys::general::FUTEX_TRYLOCK_PI,
84+
/// `FUTEX_WAIT_BITSET`
85+
WaitBitset = linux_raw_sys::general::FUTEX_WAIT_BITSET,
86+
}
87+
5588
/// `FUTEX_WAITERS`
56-
pub const FUTEX_WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS;
89+
pub const WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS;
5790

5891
/// `FUTEX_OWNER_DIED`
59-
pub const FUTEX_OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED;
92+
pub const OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED;

src/backend/linux_raw/thread/syscalls.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
//! See the `rustix::backend` module documentation for details.
66
#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
77

8-
use super::futex::FutexOperation;
98
use crate::backend::c;
109
use crate::backend::conv::{
1110
by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_usize, slice,
@@ -14,7 +13,7 @@ use crate::backend::conv::{
1413
use crate::fd::BorrowedFd;
1514
use crate::io;
1615
use crate::pid::Pid;
17-
use crate::thread::{ClockId, FutexFlags, NanosleepRelativeResult, Timespec};
16+
use crate::thread::{futex, ClockId, NanosleepRelativeResult, Timespec};
1817
use core::mem::MaybeUninit;
1918
use core::sync::atomic::AtomicU32;
2019
#[cfg(target_pointer_width = "32")]
@@ -208,14 +207,14 @@ pub(crate) fn gettid() -> Pid {
208207
#[inline]
209208
pub(crate) unsafe fn futex_val2(
210209
uaddr: *const AtomicU32,
211-
op: FutexOperation,
212-
flags: FutexFlags,
210+
op: super::futex::Operation,
211+
flags: futex::Flags,
213212
val: u32,
214213
val2: u32,
215214
uaddr2: *const AtomicU32,
216215
val3: u32,
217216
) -> io::Result<usize> {
218-
// the least significant four bytes of the timeout pointer are used as `val2`.
217+
// The least-significant four bytes of the timeout pointer are used as `val2`.
219218
// ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html),
220219
// so we perform that exact conversion in reverse to create the pointer.
221220
let timeout = val2 as usize as *const Timespec;
@@ -247,8 +246,8 @@ pub(crate) unsafe fn futex_val2(
247246
#[inline]
248247
pub(crate) unsafe fn futex_timeout(
249248
uaddr: *const AtomicU32,
250-
op: FutexOperation,
251-
flags: FutexFlags,
249+
op: super::futex::Operation,
250+
flags: futex::Flags,
252251
val: u32,
253252
timeout: *const Timespec,
254253
uaddr2: *const AtomicU32,
@@ -290,8 +289,8 @@ pub(crate) unsafe fn futex_timeout(
290289
#[cfg(target_pointer_width = "32")]
291290
unsafe fn futex_old_timespec(
292291
uaddr: *const AtomicU32,
293-
op: FutexOperation,
294-
flags: FutexFlags,
292+
op: super::futex::Operation,
293+
flags: futex::Flags,
295294
val: u32,
296295
timeout: *const Timespec,
297296
uaddr2: *const AtomicU32,
@@ -321,7 +320,6 @@ unsafe fn futex_old_timespec(
321320
c_uint(val3)
322321
))
323322
}
324-
325323
#[inline]
326324
pub(crate) fn setns(fd: BorrowedFd<'_>, nstype: c::c_int) -> io::Result<c::c_int> {
327325
unsafe { ret_c_int(syscall_readonly!(__NR_setns, fd, c_int(nstype))) }

0 commit comments

Comments
 (0)