Skip to content

Commit 0cf12f8

Browse files
committed
glib: Get rid of some unnecessary Option wrapping
1 parent a2c8bba commit 0cf12f8

File tree

3 files changed

+33
-49
lines changed

3 files changed

+33
-49
lines changed

glib/src/main_context_channel.rs

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ impl<T> Channel<T> {
199199
#[repr(C)]
200200
struct ChannelSource<T, F: FnMut(T) -> Continue + 'static> {
201201
source: ffi::GSource,
202-
source_funcs: Option<Box<ffi::GSourceFuncs>>,
203-
channel: Option<Channel<T>>,
204-
callback: Option<ThreadGuard<F>>,
202+
source_funcs: Box<ffi::GSourceFuncs>,
203+
channel: Channel<T>,
204+
callback: ThreadGuard<F>,
205205
}
206206

207207
unsafe extern "C" fn dispatch<T, F: FnMut(T) -> Continue + 'static>(
@@ -218,21 +218,13 @@ unsafe extern "C" fn dispatch<T, F: FnMut(T) -> Continue + 'static>(
218218

219219
// Get a reference to the callback. This will panic if we're called from a different
220220
// thread than where the source was attached to the main context.
221-
let callback = source
222-
.callback
223-
.as_mut()
224-
.expect("ChannelSource called before Receiver was attached")
225-
.get_mut();
221+
let callback = source.callback.get_mut();
226222

227223
// Now iterate over all items that we currently have in the channel until it is
228224
// empty again. If all senders are disconnected at some point we remove the GSource
229225
// from the main context it was attached to as it will never ever be called again.
230-
let channel = source
231-
.channel
232-
.as_ref()
233-
.expect("ChannelSource without Channel");
234226
loop {
235-
match channel.try_recv() {
227+
match source.channel.try_recv() {
236228
Err(mpsc::TryRecvError::Empty) => break,
237229
Err(mpsc::TryRecvError::Disconnected) => return ffi::G_SOURCE_REMOVE,
238230
Ok(item) => {
@@ -250,14 +242,12 @@ unsafe extern "C" fn dispatch<T, F: FnMut(T) -> Continue + 'static>(
250242
unsafe extern "C" fn dispose<T, F: FnMut(T) -> Continue + 'static>(source: *mut ffi::GSource) {
251243
let source = &mut *(source as *mut ChannelSource<T, F>);
252244

253-
if let Some(ref channel) = source.channel {
254-
// Set the source inside the channel to None so that all senders know that there
255-
// is no receiver left and wake up the condition variable if any
256-
let mut inner = (channel.0).0.lock().unwrap();
257-
inner.source = ChannelSourceState::Destroyed;
258-
if let Some(ChannelBound { ref cond, .. }) = (channel.0).1 {
259-
cond.notify_all();
260-
}
245+
// Set the source inside the channel to None so that all senders know that there
246+
// is no receiver left and wake up the condition variable if any
247+
let mut inner = (source.channel.0).0.lock().unwrap();
248+
inner.source = ChannelSourceState::Destroyed;
249+
if let Some(ChannelBound { ref cond, .. }) = (source.channel.0).1 {
250+
cond.notify_all();
261251
}
262252
}
263253

@@ -266,14 +256,8 @@ unsafe extern "C" fn finalize<T, F: FnMut(T) -> Continue + 'static>(source: *mut
266256

267257
// Drop all memory we own by taking it out of the Options
268258

269-
#[cfg(feature = "v2_64")]
270-
{
271-
let _ = source.channel.take().expect("Receiver without channel");
272-
}
273259
#[cfg(not(feature = "v2_64"))]
274260
{
275-
let channel = source.channel.take().expect("Receiver without channel");
276-
277261
// FIXME: This is the same as would otherwise be done in the dispose() function but
278262
// unfortunately it doesn't exist in older version of GLib. Doing it only here can
279263
// cause a channel sender to get a reference to the source with reference count 0
@@ -283,14 +267,14 @@ unsafe extern "C" fn finalize<T, F: FnMut(T) -> Continue + 'static>(source: *mut
283267
//
284268
// Set the source inside the channel to None so that all senders know that there
285269
// is no receiver left and wake up the condition variable if any
286-
let mut inner = (channel.0).0.lock().unwrap();
270+
let mut inner = (source.channel.0).0.lock().unwrap();
287271
inner.source = ChannelSourceState::Destroyed;
288-
if let Some(ChannelBound { ref cond, .. }) = (channel.0).1 {
272+
if let Some(ChannelBound { ref cond, .. }) = (source.channel.0).1 {
289273
cond.notify_all();
290274
}
291275
}
292-
293-
let _ = source.source_funcs.take();
276+
ptr::drop_in_place(&mut source.channel);
277+
ptr::drop_in_place(&mut source.source_funcs);
294278

295279
// Take the callback out of the source. This will panic if the value is dropped
296280
// from a different thread than where the callback was created so try to drop it
@@ -299,11 +283,10 @@ unsafe extern "C" fn finalize<T, F: FnMut(T) -> Continue + 'static>(source: *mut
299283
// This can only really happen if the caller to `attach()` gets the `Source` from the returned
300284
// `SourceId` and sends it to another thread or otherwise retrieves it from the main context,
301285
// but better safe than sorry.
302-
let callback = source
303-
.callback
304-
.take()
305-
.expect("channel source finalized twice");
306-
if !callback.is_owner() {
286+
if source.callback.is_owner() {
287+
ptr::drop_in_place(&mut source.callback);
288+
} else {
289+
let callback = ptr::read(&source.callback);
307290
let context =
308291
ffi::g_source_get_context(source as *mut ChannelSource<T, F> as *mut ffi::GSource);
309292
if !context.is_null() {
@@ -522,9 +505,9 @@ impl<T> Receiver<T> {
522505
// Store all our data inside our part of the GSource
523506
{
524507
let source = &mut *source;
525-
ptr::write(&mut source.channel, Some(channel));
526-
ptr::write(&mut source.callback, Some(ThreadGuard::new(func)));
527-
ptr::write(&mut source.source_funcs, Some(source_funcs));
508+
ptr::write(ptr::addr_of_mut!(source.channel), channel);
509+
ptr::write(ptr::addr_of_mut!(source.callback), ThreadGuard::new(func));
510+
ptr::write(ptr::addr_of_mut!(source.source_funcs), source_funcs);
528511
}
529512

530513
let source = Source::from_glib_full(mut_override(&(*source).source));

glib/src/subclass/types.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -927,9 +927,7 @@ unsafe extern "C" fn finalize<T: ObjectSubclass>(obj: *mut gobject_ffi::GObject)
927927
let priv_ptr = ptr.offset(private_offset);
928928
let priv_storage = &mut *(priv_ptr as *mut PrivateStruct<T>);
929929
ptr::drop_in_place(&mut priv_storage.imp);
930-
if let Some(instance_data) = priv_storage.instance_data.take() {
931-
drop(instance_data);
932-
}
930+
ptr::drop_in_place(&mut priv_storage.instance_data);
933931

934932
// Chain up to the parent class' finalize implementation, if any.
935933
let parent_class = &*(data.as_ref().parent_class() as *const gobject_ffi::GObjectClass);

glib/src/thread_guard.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

3-
use std::sync::atomic::{AtomicUsize, Ordering};
3+
use std::{
4+
mem, ptr,
5+
sync::atomic::{AtomicUsize, Ordering},
6+
};
47
fn next_thread_id() -> usize {
58
static COUNTER: AtomicUsize = AtomicUsize::new(0);
69
COUNTER.fetch_add(1, Ordering::SeqCst)
@@ -20,7 +23,7 @@ pub fn thread_id() -> usize {
2023
/// Thread guard that only gives access to the contained value on the thread it was created on.
2124
pub struct ThreadGuard<T> {
2225
thread_id: usize,
23-
value: Option<T>,
26+
value: T,
2427
}
2528

2629
impl<T> ThreadGuard<T> {
@@ -35,7 +38,7 @@ impl<T> ThreadGuard<T> {
3538
pub fn new(value: T) -> Self {
3639
Self {
3740
thread_id: thread_id(),
38-
value: Some(value),
41+
value,
3942
}
4043
}
4144

@@ -53,7 +56,7 @@ impl<T> ThreadGuard<T> {
5356
"Value accessed from different thread than where it was created"
5457
);
5558

56-
self.value.as_ref().unwrap()
59+
&self.value
5760
}
5861

5962
// rustdoc-stripper-ignore-next
@@ -70,7 +73,7 @@ impl<T> ThreadGuard<T> {
7073
"Value accessed from different thread than where it was created"
7174
);
7275

73-
self.value.as_mut().unwrap()
76+
&mut self.value
7477
}
7578

7679
// rustdoc-stripper-ignore-next
@@ -81,13 +84,13 @@ impl<T> ThreadGuard<T> {
8184
/// This function panics if called from a different thread than where the thread guard was
8285
/// created.
8386
#[inline]
84-
pub fn into_inner(mut self) -> T {
87+
pub fn into_inner(self) -> T {
8588
assert!(
8689
self.thread_id == thread_id(),
8790
"Value accessed from different thread than where it was created"
8891
);
8992

90-
self.value.take().expect("into_inner() called twice")
93+
unsafe { ptr::read(&mem::ManuallyDrop::new(self).value) }
9194
}
9295

9396
// rustdoc-stripper-ignore-next

0 commit comments

Comments
 (0)