[3.6] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked… · python/cpython@55ab604 (original) (raw)

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

`

466

466

`PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,

`

467

467

`int intr_flag)

`

468

468

`{

`

469

``

`-

PyLockStatus success;

`

``

469

`+

PyLockStatus success = PY_LOCK_FAILURE;

`

470

470

`pthread_lock *thelock = (pthread_lock *)lock;

`

471

471

`int status, error = 0;

`

472

472

``

473

473

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

`

474

474

`lock, microseconds, intr_flag));

`

475

475

``

476

``

`-

status = pthread_mutex_lock( &thelock->mut );

`

477

``

`-

CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");

`

478

``

-

479

``

`-

if (thelock->locked == 0) {

`

480

``

`-

success = PY_LOCK_ACQUIRED;

`

481

``

`-

} else if (microseconds == 0) {

`

482

``

`-

success = PY_LOCK_FAILURE;

`

483

``

`-

} else {

`

484

``

`-

struct timespec ts;

`

485

``

`-

if (microseconds > 0)

`

486

``

`-

MICROSECONDS_TO_TIMESPEC(microseconds, ts);

`

487

``

`-

/* continue trying until we get the lock */

`

488

``

-

489

``

`-

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

`

490

``

`-

`

491

``

`-

success = PY_LOCK_FAILURE;

`

492

``

`-

while (success == PY_LOCK_FAILURE) {

`

493

``

`-

if (microseconds > 0) {

`

494

``

`-

status = pthread_cond_timedwait(

`

495

``

`-

&thelock->lock_released,

`

496

``

`-

&thelock->mut, &ts);

`

497

``

`-

if (status == ETIMEDOUT)

`

``

476

`+

if (microseconds == 0) {

`

``

477

`+

status = pthread_mutex_trylock( &thelock->mut );

`

``

478

`+

if (status != EBUSY)

`

``

479

`+

CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");

`

``

480

`+

}

`

``

481

`+

else {

`

``

482

`+

status = pthread_mutex_lock( &thelock->mut );

`

``

483

`+

CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");

`

``

484

`+

}

`

``

485

`+

if (status == 0) {

`

``

486

`+

if (thelock->locked == 0) {

`

``

487

`+

success = PY_LOCK_ACQUIRED;

`

``

488

`+

}

`

``

489

`+

else if (microseconds != 0) {

`

``

490

`+

struct timespec ts;

`

``

491

`+

if (microseconds > 0)

`

``

492

`+

MICROSECONDS_TO_TIMESPEC(microseconds, ts);

`

``

493

`+

/* continue trying until we get the lock */

`

``

494

+

``

495

`+

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

`

``

496

`+

`

``

497

`+

while (success == PY_LOCK_FAILURE) {

`

``

498

`+

if (microseconds > 0) {

`

``

499

`+

status = pthread_cond_timedwait(

`

``

500

`+

&thelock->lock_released,

`

``

501

`+

&thelock->mut, &ts);

`

``

502

`+

if (status == ETIMEDOUT)

`

``

503

`+

break;

`

``

504

`+

CHECK_STATUS_PTHREAD("pthread_cond_timed_wait");

`

``

505

`+

}

`

``

506

`+

else {

`

``

507

`+

status = pthread_cond_wait(

`

``

508

`+

&thelock->lock_released,

`

``

509

`+

&thelock->mut);

`

``

510

`+

CHECK_STATUS_PTHREAD("pthread_cond_wait");

`

``

511

`+

}

`

``

512

+

``

513

`+

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

`

``

514

`+

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

`

``

515

`+

`

``

516

`+

`

``

517

`+

success = PY_LOCK_INTR;

`

498

518

`break;

`

499

``

`-

CHECK_STATUS_PTHREAD("pthread_cond_timed_wait");

`

500

``

`-

}

`

501

``

`-

else {

`

502

``

`-

status = pthread_cond_wait(

`

503

``

`-

&thelock->lock_released,

`

504

``

`-

&thelock->mut);

`

505

``

`-

CHECK_STATUS_PTHREAD("pthread_cond_wait");

`

506

``

`-

}

`

507

``

-

508

``

`-

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

`

509

``

`-

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

`

510

``

`-

`

511

``

`-

`

512

``

`-

success = PY_LOCK_INTR;

`

513

``

`-

break;

`

514

``

`-

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

`

515

``

`-

success = PY_LOCK_ACQUIRED;

`

516

``

`-

} else {

`

517

``

`-

success = PY_LOCK_FAILURE;

`

``

519

`+

}

`

``

520

`+

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

`

``

521

`+

success = PY_LOCK_ACQUIRED;

`

``

522

`+

}

`

518

523

` }

`

519

524

` }

`

``

525

`+

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

`

``

526

`+

status = pthread_mutex_unlock( &thelock->mut );

`

``

527

`+

CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");

`

520

528

` }

`

521

``

`-

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

`

522

``

`-

status = pthread_mutex_unlock( &thelock->mut );

`

523

``

`-

CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");

`

524

529

``

525

530

`if (error) success = PY_LOCK_FAILURE;

`

526

531

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

`