diff options
| author | Robert Haas | 2017-03-29 13:44:29 +0000 |
|---|---|---|
| committer | Robert Haas | 2017-03-29 13:48:39 +0000 |
| commit | fddf45b38097d14301d249fbeebca32e40233bd2 (patch) | |
| tree | 9f8fa462f059b3a18ef02380570084e6b1c18717 /src/backend | |
| parent | 3582b223d494cd505c6a22da98bcb49f99196645 (diff) | |
Plug race in dsa_attach.
With sufficiently bad luck, it was possible for a parallel worker to
attempt attach to a DSA area after all other backends have detached
from it, which is not legal. If the worker had waited a little longer
to get started, the DSM itself would have been destroyed, which is why
this wasn't noticed before.
Thomas Munro, per a report from Andreas Seltenreich
Discussion: http://postgr.es/m/87h92g83t3.fsf@credativ.de
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/utils/mmgr/dsa.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index 6d5d12a6c9d..d08317249bb 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -1314,6 +1314,13 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle) /* Bump the reference count. */ LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); + if (control->refcnt == 0) + { + /* We can't attach to a DSA area that has already been destroyed. */ + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("could not attach to dsa_area"))); + } ++control->refcnt; LWLockRelease(DSA_AREA_LOCK(area)); |
