Skip to content

Commit f10798e

Browse files
committed
Refactored
1 parent e94c7d8 commit f10798e

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

tokio/src/runtime/task/harness.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,17 @@ where
339339
// in task/mod.rs, since the JOIN_WAKER bit is set and the call
340340
// to transition_to_complete() above set the COMPLETE bit.
341341
self.trailer().wake_join();
342+
343+
// If JOIN_INTEREST is still set at this point the `JoinHandle` was not
344+
// dropped since setting COMPLETE so we unset JOIN_WAKER so that the
345+
// `JoinHandle` is able to drop the waker when itself gets dropped.
346+
if self.state().unset_waker_if_join_interested().is_err() {
347+
// If JOIN_INTEREST got unset since setting COMPLETE we need to drop
348+
// the waker here because the `JoinHandle` is already dropped.
349+
unsafe {
350+
self.trailer().set_waker(None);
351+
}
352+
}
342353
}
343354
}));
344355

@@ -355,15 +366,6 @@ where
355366
}));
356367
}
357368

358-
if snapshot.is_join_interested() && snapshot.is_join_waker_set() {
359-
// If JOIN_INTEREST and JOIN_WAKER are still set at this point, the runtime should
360-
// drop the join waker as the join handle is not allowed to modify the waker
361-
// following rule 6 in task/mod.rs
362-
unsafe {
363-
self.trailer().set_waker(None);
364-
}
365-
}
366-
367369
// The task has completed execution and will no longer be scheduled.
368370
let num_release = self.release();
369371

tokio/src/runtime/task/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
//! * `RUNNING` - Tracks whether the task is currently being polled or cancelled.
3838
//! This bit functions as a lock around the task.
3939
//!
40-
//! * `COMPLETE` - Is one once the future has fully completed and the future is
40+
//! * `COMPLETE` - Is one once the future has fully completed and has been
4141
//! dropped. Never unset once set. Never set together with RUNNING.
4242
//!
4343
//! * `NOTIFIED` - Tracks whether a Notified object currently exists.

tokio/src/runtime/task/state.rs

+39-22
Original file line numberDiff line numberDiff line change
@@ -190,24 +190,14 @@ impl State {
190190
///
191191
/// Returns true if the task should be deallocated.
192192
pub(super) fn transition_to_terminal(&self, count: usize) -> bool {
193-
self.fetch_update_action(|mut snapshot| {
194-
assert!(
195-
snapshot.ref_count() >= count,
196-
"current: {}, sub: {}",
197-
snapshot.ref_count(),
198-
count
199-
);
200-
201-
snapshot.0 -= count * REF_ONE;
202-
if snapshot.is_join_interested() {
203-
// If there is still a join handle alive at this point we unset the
204-
// JOIN_WAKER bit so that the join handle gains exclusive access to
205-
// the waker field to actually drop it.
206-
snapshot.unset_join_waker();
207-
}
208-
209-
(snapshot.ref_count() == 0, Some(snapshot))
210-
})
193+
let prev = Snapshot(self.val.fetch_sub(count * REF_ONE, AcqRel));
194+
assert!(
195+
prev.ref_count() >= count,
196+
"current: {}, sub: {}",
197+
prev.ref_count(),
198+
count
199+
);
200+
prev.ref_count() == count
211201
}
212202

213203
/// Transitions the state to `NOTIFIED`.
@@ -389,13 +379,20 @@ impl State {
389379
self.fetch_update(|curr| {
390380
assert!(curr.is_join_interested());
391381

392-
if curr.is_complete() {
393-
return None;
394-
}
382+
// if curr.is_complete() {
383+
// return None;
384+
// }
385+
386+
// let mut next = curr;
387+
// next.unset_join_interested();
388+
389+
// Some(next)
395390

396391
let mut next = curr;
397392
next.unset_join_interested();
398-
393+
if !curr.is_complete() {
394+
next.unset_join_waker();
395+
}
399396
Some(next)
400397
})
401398
}
@@ -440,6 +437,26 @@ impl State {
440437
})
441438
}
442439

440+
/// Unsets the `JOIN_WAKER` bit only if the `JOIN_INTEREST` is still set.
441+
///
442+
/// Returns `Ok` has been unset, `Err` otherwise. This operation requires
443+
/// the task to be completed.
444+
pub(super) fn unset_waker_if_join_interested(&self) -> UpdateResult {
445+
self.fetch_update(|curr| {
446+
assert!(curr.is_complete());
447+
assert!(curr.is_join_waker_set());
448+
449+
if !curr.is_join_interested() {
450+
return None;
451+
}
452+
453+
let mut next = curr;
454+
next.unset_join_waker();
455+
456+
Some(next)
457+
})
458+
}
459+
443460
pub(super) fn ref_inc(&self) {
444461
use std::process;
445462
use std::sync::atomic::Ordering::Relaxed;

0 commit comments

Comments
 (0)