std: fix busy-waiting in Once::wait_force, add more tests · patricklam/verify-rust-std@cc6f37f (original) (raw)

`@@ -153,7 +153,7 @@ impl Once {

`

153

153

`panic!("Once instance has previously been poisoned");

`

154

154

`}

`

155

155

` _ => {

`

156

``

`-

current = wait(&self.state_and_queue, current);

`

``

156

`+

current = wait(&self.state_and_queue, current, !ignore_poisoning);

`

157

157

`}

`

158

158

`}

`

159

159

`}

`

`@@ -216,14 +216,18 @@ impl Once {

`

216

216

`// All other values must be RUNNING with possibly a

`

217

217

`// pointer to the waiter queue in the more significant bits.

`

218

218

`assert!(state == RUNNING);

`

219

``

`-

current = wait(&self.state_and_queue, current);

`

``

219

`+

current = wait(&self.state_and_queue, current, true);

`

220

220

`}

`

221

221

`}

`

222

222

`}

`

223

223

`}

`

224

224

`}

`

225

225

``

226

``

`-

fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAndQueue {

`

``

226

`+

fn wait(

`

``

227

`+

state_and_queue: &AtomicPtr<()>,

`

``

228

`+

mut current: StateAndQueue,

`

``

229

`+

return_on_poisoned: bool,

`

``

230

`+

) -> StateAndQueue {

`

227

231

`let node = &Waiter {

`

228

232

`thread: Cell::new(Some(thread::current())),

`

229

233

`signaled: AtomicBool::new(false),

`

`@@ -235,7 +239,7 @@ fn wait(state_and_queue: &AtomicPtr<()>, mut current: StateAndQueue) -> StateAnd

`

235

239

`let queue = to_queue(current);

`

236

240

``

237

241

`// If initialization has finished, return.

`

238

``

`-

if matches!(state, POISONED | COMPLETE) {

`

``

242

`+

if state == COMPLETE || (return_on_poisoned && state == POISONED) {

`

239

243

`return current;

`

240

244

`}

`

241

245

``