Rollup merge of #128092 - ChrisDenton:wrappers, r=workingjubilee · model-checking/verify-rust-std@de086ea (original) (raw)

`@@ -238,15 +238,6 @@ fn random_number() -> usize {

`

238

238

`}

`

239

239

`}

`

240

240

``

241

``

`` -

// Abstracts over ReadFileEx and WriteFileEx

``

242

``

`-

type AlertableIoFn = unsafe extern "system" fn(

`

243

``

`-

BorrowedHandle<'_>,

`

244

``

`-

*mut core::ffi::c_void,

`

245

``

`-

u32,

`

246

``

`-

*mut c::OVERLAPPED,

`

247

``

`-

c::LPOVERLAPPED_COMPLETION_ROUTINE,

`

248

``

`-

) -> c::BOOL;

`

249

``

-

250

241

`impl AnonPipe {

`

251

242

`pub fn handle(&self) -> &Handle {

`

252

243

`&self.inner

`

`@@ -262,7 +253,10 @@ impl AnonPipe {

`

262

253

`pub fn read(&self, buf: &mut [u8]) -> io::Result {

`

263

254

`let result = unsafe {

`

264

255

`let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;

`

265

``

`-

self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)

`

``

256

`+

let ptr = buf.as_mut_ptr();

`

``

257

`+

self.alertable_io_internal(|overlapped, callback| {

`

``

258

`+

c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)

`

``

259

`+

})

`

266

260

`};

`

267

261

``

268

262

`match result {

`

`@@ -278,7 +272,10 @@ impl AnonPipe {

`

278

272

`pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {

`

279

273

`let result = unsafe {

`

280

274

`let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32;

`

281

``

`-

self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len)

`

``

275

`+

let ptr = buf.as_mut().as_mut_ptr().cast::();

`

``

276

`+

self.alertable_io_internal(|overlapped, callback| {

`

``

277

`+

c::ReadFileEx(self.inner.as_raw_handle(), ptr, len, overlapped, callback)

`

``

278

`+

})

`

282

279

`};

`

283

280

``

284

281

`match result {

`

`@@ -313,7 +310,9 @@ impl AnonPipe {

`

313

310

`pub fn write(&self, buf: &[u8]) -> io::Result {

`

314

311

`unsafe {

`

315

312

`let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;

`

316

``

`-

self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)

`

``

313

`+

self.alertable_io_internal(|overlapped, callback| {

`

``

314

`+

c::WriteFileEx(self.inner.as_raw_handle(), buf.as_ptr(), len, overlapped, callback)

`

``

315

`+

})

`

317

316

`}

`

318

317

`}

`

319

318

``

`@@ -341,12 +340,9 @@ impl AnonPipe {

`

341

340

`` /// [ReadFileEx]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex

``

342

341

`` /// [WriteFileEx]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex

``

343

342

`/// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls

`

344

``

`-

#[allow(unsafe_op_in_unsafe_fn)]

`

345

343

`unsafe fn alertable_io_internal(

`

346

344

`&self,

`

347

``

`-

io: AlertableIoFn,

`

348

``

`-

buf: *mut core::ffi::c_void,

`

349

``

`-

len: u32,

`

``

345

`+

io: impl FnOnce(&mut c::OVERLAPPED, c::LPOVERLAPPED_COMPLETION_ROUTINE) -> c::BOOL,

`

350

346

`) -> io::Result {

`

351

347

`// Use "alertable I/O" to synchronize the pipe I/O.

`

352

348

`// This has four steps.

`

`@@ -384,20 +380,25 @@ impl AnonPipe {

`

384

380

`lpOverlapped: *mut c::OVERLAPPED,

`

385

381

`) {

`

386

382

`` // Set async_result using a pointer smuggled through hEvent.

``

387

``

`-

let result =

`

388

``

`-

AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };

`

389

``

`-

*(*lpOverlapped).hEvent.cast::<Option>() = Some(result);

`

``

383

`+

// SAFETY:

`

``

384

`+

// At this point, the OVERLAPPED struct will have been written to by the OS,

`

``

385

`` +

// except for our hEvent field which we set to a valid AsyncResult pointer (see below)

``

``

386

`+

unsafe {

`

``

387

`+

let result =

`

``

388

`+

AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };

`

``

389

`+

*(*lpOverlapped).hEvent.cast::<Option>() = Some(result);

`

``

390

`+

}

`

390

391

`}

`

391

392

``

392

393

`// STEP 1: Start the I/O operation.

`

393

``

`-

let mut overlapped: c::OVERLAPPED = crate::mem::zeroed();

`

``

394

`+

let mut overlapped: c::OVERLAPPED = unsafe { crate::mem::zeroed() };

`

394

395

`` // hEvent is unused by ReadFileEx and WriteFileEx.

``

395

396

`// Therefore the documentation suggests using it to smuggle a pointer to the callback.

`

396

397

` overlapped.hEvent = core::ptr::addr_of_mut!(async_result) as *mut _;

`

397

398

``

398

399

`// Asynchronous read of the pipe.

`

399

400

`` // If successful, callback will be called once it completes.

``

400

``

`-

let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback));

`

``

401

`+

let result = io(&mut overlapped, Some(callback));

`

401

402

`if result == c::FALSE {

`

402

403

`// We can return here because the call failed.

`

403

404

`// After this we must not return until the I/O completes.

`

`@@ -408,7 +409,7 @@ impl AnonPipe {

`

408

409

`let result = loop {

`

409

410

`// STEP 2: Enter an alertable state.

`

410

411

`` // The second parameter of SleepEx is used to make this sleep alertable.

``

411

``

`-

c::SleepEx(c::INFINITE, c::TRUE);

`

``

412

`+

unsafe { c::SleepEx(c::INFINITE, c::TRUE) };

`

412

413

`if let Some(result) = async_result {

`

413

414

`break result;

`

414

415

`}

`