Skip to content

Commit a7c2e21

Browse files
committed
remove the entry API subset
1 parent ccc5af2 commit a7c2e21

File tree

2 files changed

+31
-64
lines changed

2 files changed

+31
-64
lines changed

signal-hook-registry/src/lib.rs

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ use libc::{SIGFPE, SIGILL, SIGKILL, SIGSEGV, SIGSTOP};
8888
use libc::{SIGFPE, SIGILL, SIGSEGV};
8989

9090
use half_lock::HalfLock;
91-
use vec_map::{Entry, VecMap};
91+
use vec_map::VecMap;
9292

9393
// These constants are not defined in the current version of libc, but it actually
9494
// exists in Windows CRT.
@@ -630,34 +630,32 @@ unsafe fn register_unchecked_impl(signal: c_int, action: Arc<Action>) -> Result<
630630
let id = ActionId(sigdata.next_id);
631631
sigdata.next_id += 1;
632632

633-
match sigdata.signals.entry(signal) {
634-
Entry::Occupied(mut occupied) => {
635-
assert!(occupied.get_mut().actions.insert(id, action).is_none());
636-
}
637-
Entry::Vacant(place) => {
638-
// While the sigaction/signal exchanges the old one atomically, we are not able to
639-
// atomically store it somewhere a signal handler could read it. That poses a race
640-
// condition where we could lose some signals delivered in between changing it and
641-
// storing it.
642-
//
643-
// Therefore we first store the old one in the fallback storage. The fallback only
644-
// covers the cases where the slot is not yet active and becomes "inert" after that,
645-
// even if not removed (it may get overwritten by some other signal, but for that the
646-
// mutex in globals.data must be unlocked here - and by that time we already stored the
647-
// slot.
648-
//
649-
// And yes, this still leaves a short race condition when some other thread could
650-
// replace the signal handler and we would be calling the outdated one for a short
651-
// time, until we install the slot.
652-
globals
653-
.race_fallback
654-
.write()
655-
.store(Some(Prev::detect(signal)?));
656-
657-
let mut slot = Slot::new(signal)?;
658-
slot.actions.insert(id, action);
659-
place.insert(slot);
660-
}
633+
if sigdata.signals.contains(&signal) {
634+
let slot = sigdata.signals.get_mut(&signal).unwrap();
635+
assert!(slot.actions.insert(id, action).is_none());
636+
} else {
637+
// While the sigaction/signal exchanges the old one atomically, we are not able to
638+
// atomically store it somewhere a signal handler could read it. That poses a race
639+
// condition where we could lose some signals delivered in between changing it and
640+
// storing it.
641+
//
642+
// Therefore we first store the old one in the fallback storage. The fallback only
643+
// covers the cases where the slot is not yet active and becomes "inert" after that,
644+
// even if not removed (it may get overwritten by some other signal, but for that the
645+
// mutex in globals.data must be unlocked here - and by that time we already stored the
646+
// slot.
647+
//
648+
// And yes, this still leaves a short race condition when some other thread could
649+
// replace the signal handler and we would be calling the outdated one for a short
650+
// time, until we install the slot.
651+
globals
652+
.race_fallback
653+
.write()
654+
.store(Some(Prev::detect(signal)?));
655+
656+
let mut slot = Slot::new(signal)?;
657+
slot.actions.insert(id, action);
658+
sigdata.signals.insert(signal, slot);
661659
}
662660

663661
lock.store(sigdata);

signal-hook-registry/src/vec_map.rs

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ impl<K: Eq, V> VecMap<K, V> {
2929
None
3030
}
3131

32+
pub fn contains(&self, key: &K) -> bool {
33+
self.find(key).is_some()
34+
}
35+
3236
pub fn get(&self, key: &K) -> Option<&V> {
3337
match self.find(key) {
3438
Some(i) => Some(&self.0[i].1),
@@ -58,42 +62,7 @@ impl<K: Eq, V> VecMap<K, V> {
5862
}
5963
}
6064

61-
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
62-
match self.find(&key) {
63-
Some(i) => Entry::Occupied(OccupiedEntry {
64-
place: &mut self.0[i],
65-
}),
66-
None => Entry::Vacant(VacantEntry { map: self, key }),
67-
}
68-
}
69-
7065
pub fn values(&self) -> impl Iterator<Item = &V> {
7166
self.0.iter().map(|kv| &kv.1)
7267
}
7368
}
74-
75-
pub enum Entry<'a, K: 'a, V: 'a> {
76-
Occupied(OccupiedEntry<'a, K, V>),
77-
Vacant(VacantEntry<'a, K, V>),
78-
}
79-
80-
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
81-
place: &'a mut (K, V),
82-
}
83-
84-
impl<'a, K, V> OccupiedEntry<'a, K, V> {
85-
pub fn get_mut(&mut self) -> &mut V {
86-
&mut self.place.1
87-
}
88-
}
89-
90-
pub struct VacantEntry<'a, K: 'a, V: 'a> {
91-
map: &'a mut VecMap<K, V>,
92-
key: K,
93-
}
94-
95-
impl<'a, K, V> VacantEntry<'a, K, V> {
96-
pub fn insert(self, value: V) {
97-
self.map.0.push((self.key, value));
98-
}
99-
}

0 commit comments

Comments
 (0)