|
55 | 55 | /* GUC variables */
|
56 | 56 | intDeadlockTimeout=1000;
|
57 | 57 | intStatementTimeout=0;
|
| 58 | +intLockTimeout=0; |
58 | 59 | boollog_lock_waits= false;
|
59 | 60 |
|
60 | 61 | /* Pointer to this process's PGPROC and PGXACT structs, if any */
|
@@ -665,15 +666,27 @@ void
|
665 | 666 | LockErrorCleanup(void)
|
666 | 667 | {
|
667 | 668 | LWLockIdpartitionLock;
|
| 669 | +DisableTimeoutParamstimeouts[2]; |
668 | 670 |
|
669 | 671 | AbortStrongLockAcquire();
|
670 | 672 |
|
671 | 673 | /* Nothing to do if we weren't waiting for a lock */
|
672 | 674 | if (lockAwaited==NULL)
|
673 | 675 | return;
|
674 | 676 |
|
675 |
| -/* Turn off the deadlock timer, if it's still running (see ProcSleep) */ |
676 |
| -disable_timeout(DEADLOCK_TIMEOUT, false); |
| 677 | +/* |
| 678 | + * Turn off the deadlock and lock timeout timers, if they are still |
| 679 | + * running (see ProcSleep). Note we must preserve the LOCK_TIMEOUT |
| 680 | + * indicator flag, since this function is executed before |
| 681 | + * ProcessInterrupts when responding to SIGINT; else we'd lose the |
| 682 | + * knowledge that the SIGINT came from a lock timeout and not an external |
| 683 | + * source. |
| 684 | + */ |
| 685 | +timeouts[0].id=DEADLOCK_TIMEOUT; |
| 686 | +timeouts[0].keep_indicator= false; |
| 687 | +timeouts[1].id=LOCK_TIMEOUT; |
| 688 | +timeouts[1].keep_indicator= true; |
| 689 | +disable_timeouts(timeouts,2); |
677 | 690 |
|
678 | 691 | /* Unlink myself from the wait queue, if on it (might not be anymore!) */
|
679 | 692 | partitionLock=LockHashPartitionLock(lockAwaited->hashcode);
|
@@ -1072,8 +1085,24 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
|
1072 | 1085 | *
|
1073 | 1086 | * By delaying the check until we've waited for a bit, we can avoid
|
1074 | 1087 | * running the rather expensive deadlock-check code in most cases.
|
| 1088 | + * |
| 1089 | + * If LockTimeout is set, also enable the timeout for that. We can save a |
| 1090 | + * few cycles by enabling both timeout sources in one call. |
1075 | 1091 | */
|
1076 |
| -enable_timeout_after(DEADLOCK_TIMEOUT,DeadlockTimeout); |
| 1092 | +if (LockTimeout>0) |
| 1093 | +{ |
| 1094 | +EnableTimeoutParamstimeouts[2]; |
| 1095 | + |
| 1096 | +timeouts[0].id=DEADLOCK_TIMEOUT; |
| 1097 | +timeouts[0].type=TMPARAM_AFTER; |
| 1098 | +timeouts[0].delay_ms=DeadlockTimeout; |
| 1099 | +timeouts[1].id=LOCK_TIMEOUT; |
| 1100 | +timeouts[1].type=TMPARAM_AFTER; |
| 1101 | +timeouts[1].delay_ms=LockTimeout; |
| 1102 | +enable_timeouts(timeouts,2); |
| 1103 | +} |
| 1104 | +else |
| 1105 | +enable_timeout_after(DEADLOCK_TIMEOUT,DeadlockTimeout); |
1077 | 1106 |
|
1078 | 1107 | /*
|
1079 | 1108 | * If someone wakes us between LWLockRelease and PGSemaphoreLock,
|
@@ -1240,9 +1269,20 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
|
1240 | 1269 | }while (myWaitStatus==STATUS_WAITING);
|
1241 | 1270 |
|
1242 | 1271 | /*
|
1243 |
| - * Disable thetimer, ifit's still running |
| 1272 | + * Disable thetimers, ifthey are still running |
1244 | 1273 | */
|
1245 |
| -disable_timeout(DEADLOCK_TIMEOUT, false); |
| 1274 | +if (LockTimeout>0) |
| 1275 | +{ |
| 1276 | +DisableTimeoutParamstimeouts[2]; |
| 1277 | + |
| 1278 | +timeouts[0].id=DEADLOCK_TIMEOUT; |
| 1279 | +timeouts[0].keep_indicator= false; |
| 1280 | +timeouts[1].id=LOCK_TIMEOUT; |
| 1281 | +timeouts[1].keep_indicator= false; |
| 1282 | +disable_timeouts(timeouts,2); |
| 1283 | +} |
| 1284 | +else |
| 1285 | +disable_timeout(DEADLOCK_TIMEOUT, false); |
1246 | 1286 |
|
1247 | 1287 | /*
|
1248 | 1288 | * Re-acquire the lock table's partition lock. We have to do this to hold
|
|