diff --git a/.pick_status.json b/.pick_status.json index e129ea3e151..55fc119d5a8 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -664,7 +664,7 @@ "description": "rusticl/queue: Only take a weak ref to the last Event", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "5b3ff7e3f3d0e35f7bc17d9f208a8aeee3062427", "notes": null diff --git a/src/gallium/frontends/rusticl/core/queue.rs b/src/gallium/frontends/rusticl/core/queue.rs index 364b4272487..4a4cb223949 100644 --- a/src/gallium/frontends/rusticl/core/queue.rs +++ b/src/gallium/frontends/rusticl/core/queue.rs @@ -13,12 +13,13 @@ use std::collections::HashSet; use std::sync::mpsc; use std::sync::Arc; use std::sync::Mutex; +use std::sync::Weak; use std::thread; use std::thread::JoinHandle; struct QueueState { pending: Vec>, - last: Option>, + last: Weak, // `Sync` on `Sender` was stabilized in 1.72, until then, put it into our Mutex. // see https://github.com/rust-lang/rust/commit/5f56956b3c7edb9801585850d1f41b0aeb1888ff chan_in: mpsc::Sender>>, @@ -62,7 +63,7 @@ impl Queue { props_v2: props_v2, state: Mutex::new(QueueState { pending: Vec::new(), - last: None, + last: Weak::new(), chan_in: tx_q, }), _thrd: thread::Builder::new() @@ -134,7 +135,7 @@ impl Queue { // Update last if and only if we get new events, this prevents breaking application code // doing things like `clFlush(q); clFinish(q);` if let Some(last) = state.pending.last() { - state.last = Some(last.clone()); + state.last = Arc::downgrade(last); } let events = state.pending.drain(0..).collect(); @@ -144,9 +145,10 @@ impl Queue { .send(events) .map_err(|_| CL_OUT_OF_HOST_MEMORY)?; if wait { - // Waiting on the last event is good enough here as the queue will process it in order, - // also take the value so we can release the event once we are done - state.last.take().map(|e| e.wait()); + // Waiting on the last event is good enough here as the queue will process it in order + // It's not a problem if the weak ref is invalid as that means the work is already done + // and waiting isn't necessary anymore. + state.last.upgrade().map(|e| e.wait()); } Ok(()) }