[3.5] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked… · python/cpython@85b34ed (original) (raw)

`@@ -464,61 +464,66 @@ PyLockStatus

`

464

464

`PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,

`

465

465

`int intr_flag)

`

466

466

`{

`

467

``

`-

PyLockStatus success;

`

``

467

`+

PyLockStatus success = PY_LOCK_FAILURE;

`

468

468

`pthread_lock *thelock = (pthread_lock *)lock;

`

469

469

`int status, error = 0;

`

470

470

``

471

471

`dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",

`

472

472

`lock, microseconds, intr_flag));

`

473

473

``

474

``

`-

status = pthread_mutex_lock( &thelock->mut );

`

475

``

`-

CHECK_STATUS("pthread_mutex_lock[1]");

`

476

``

-

477

``

`-

if (thelock->locked == 0) {

`

478

``

`-

success = PY_LOCK_ACQUIRED;

`

479

``

`-

} else if (microseconds == 0) {

`

480

``

`-

success = PY_LOCK_FAILURE;

`

481

``

`-

} else {

`

482

``

`-

struct timespec ts;

`

483

``

`-

if (microseconds > 0)

`

484

``

`-

MICROSECONDS_TO_TIMESPEC(microseconds, ts);

`

485

``

`-

/* continue trying until we get the lock */

`

486

``

-

487

``

`-

/* mut must be locked by me -- part of the condition

`

488

``

`-

`

489

``

`-

success = PY_LOCK_FAILURE;

`

490

``

`-

while (success == PY_LOCK_FAILURE) {

`

491

``

`-

if (microseconds > 0) {

`

492

``

`-

status = pthread_cond_timedwait(

`

493

``

`-

&thelock->lock_released,

`

494

``

`-

&thelock->mut, &ts);

`

495

``

`-

if (status == ETIMEDOUT)

`

``

474

`+

if (microseconds == 0) {

`

``

475

`+

status = pthread_mutex_trylock( &thelock->mut );

`

``

476

`+

if (status != EBUSY)

`

``

477

`+

CHECK_STATUS("pthread_mutex_trylock[1]");

`

``

478

`+

}

`

``

479

`+

else {

`

``

480

`+

status = pthread_mutex_lock( &thelock->mut );

`

``

481

`+

CHECK_STATUS("pthread_mutex_lock[1]");

`

``

482

`+

}

`

``

483

`+

if (status == 0) {

`

``

484

`+

if (thelock->locked == 0) {

`

``

485

`+

success = PY_LOCK_ACQUIRED;

`

``

486

`+

}

`

``

487

`+

else if (microseconds != 0) {

`

``

488

`+

struct timespec ts;

`

``

489

`+

if (microseconds > 0)

`

``

490

`+

MICROSECONDS_TO_TIMESPEC(microseconds, ts);

`

``

491

`+

/* continue trying until we get the lock */

`

``

492

+

``

493

`+

/* mut must be locked by me -- part of the condition

`

``

494

`+

`

``

495

`+

while (success == PY_LOCK_FAILURE) {

`

``

496

`+

if (microseconds > 0) {

`

``

497

`+

status = pthread_cond_timedwait(

`

``

498

`+

&thelock->lock_released,

`

``

499

`+

&thelock->mut, &ts);

`

``

500

`+

if (status == ETIMEDOUT)

`

``

501

`+

break;

`

``

502

`+

CHECK_STATUS("pthread_cond_timed_wait");

`

``

503

`+

}

`

``

504

`+

else {

`

``

505

`+

status = pthread_cond_wait(

`

``

506

`+

&thelock->lock_released,

`

``

507

`+

&thelock->mut);

`

``

508

`+

CHECK_STATUS("pthread_cond_wait");

`

``

509

`+

}

`

``

510

+

``

511

`+

if (intr_flag && status == 0 && thelock->locked) {

`

``

512

`+

/* We were woken up, but didn't get the lock. We probably received

`

``

513

`+

`

``

514

`+

`

``

515

`+

success = PY_LOCK_INTR;

`

496

516

`break;

`

497

``

`-

CHECK_STATUS("pthread_cond_timed_wait");

`

498

``

`-

}

`

499

``

`-

else {

`

500

``

`-

status = pthread_cond_wait(

`

501

``

`-

&thelock->lock_released,

`

502

``

`-

&thelock->mut);

`

503

``

`-

CHECK_STATUS("pthread_cond_wait");

`

504

``

`-

}

`

505

``

-

506

``

`-

if (intr_flag && status == 0 && thelock->locked) {

`

507

``

`-

/* We were woken up, but didn't get the lock. We probably received

`

508

``

`-

`

509

``

`-

`

510

``

`-

success = PY_LOCK_INTR;

`

511

``

`-

break;

`

512

``

`-

} else if (status == 0 && !thelock->locked) {

`

513

``

`-

success = PY_LOCK_ACQUIRED;

`

514

``

`-

} else {

`

515

``

`-

success = PY_LOCK_FAILURE;

`

``

517

`+

}

`

``

518

`+

else if (status == 0 && !thelock->locked) {

`

``

519

`+

success = PY_LOCK_ACQUIRED;

`

``

520

`+

}

`

516

521

` }

`

517

522

` }

`

``

523

`+

if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;

`

``

524

`+

status = pthread_mutex_unlock( &thelock->mut );

`

``

525

`+

CHECK_STATUS("pthread_mutex_unlock[1]");

`

518

526

` }

`

519

``

`-

if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;

`

520

``

`-

status = pthread_mutex_unlock( &thelock->mut );

`

521

``

`-

CHECK_STATUS("pthread_mutex_unlock[1]");

`

522

527

``

523

528

`if (error) success = PY_LOCK_FAILURE;

`

524

529

`dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",

`