summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas2017-03-29 13:44:29 +0000
committerRobert Haas2017-03-29 13:48:39 +0000
commitfddf45b38097d14301d249fbeebca32e40233bd2 (patch)
tree9f8fa462f059b3a18ef02380570084e6b1c18717
parent3582b223d494cd505c6a22da98bcb49f99196645 (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/[email protected]
-rw-r--r--src/backend/utils/mmgr/dsa.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index 6d5d12a6c9..d08317249b 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));