Reserve zero as an invalid DSM handle.
authorRobert Haas <rhaas@postgresql.org>
Tue, 15 Nov 2016 21:30:35 +0000 (16:30 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 15 Nov 2016 21:33:29 +0000 (16:33 -0500)
Previously, the handle for the control segment could not be zero, but
some other DSM segment could potentially have a handle value of zero.
However, that means that if someone wanted to store a dsm_handle that
might or might not be valid, they would need a separate boolean to
keep track of whether the associated value is legal.  That's annoying,
so change things so that no DSM segment can ever have a handle of 0 -
or as we call it here, DSM_HANDLE_INVALID.

Thomas Munro.  This was submitted as part of a much larger patch to
add an malloc-like allocator for dynamic shared memory, but this part
seems like a good idea independently of the rest of the patch.

src/backend/storage/ipc/dsm.c
src/include/storage/dsm.h

index d8066647a07598b63188635d167a8e6ab8ba96f5..8c6abe3b45bcbd210dd7be180f94208002169788 100644 (file)
@@ -182,7 +182,7 @@ dsm_postmaster_startup(PGShmemHeader *shim)
        Assert(dsm_control_address == NULL);
        Assert(dsm_control_mapped_size == 0);
        dsm_control_handle = random();
-       if (dsm_control_handle == 0)
+       if (dsm_control_handle == DSM_HANDLE_INVALID)
            continue;
        if (dsm_impl_op(DSM_OP_CREATE, dsm_control_handle, segsize,
                        &dsm_control_impl_private, &dsm_control_address,
@@ -476,6 +476,8 @@ dsm_create(Size size, int flags)
    {
        Assert(seg->mapped_address == NULL && seg->mapped_size == 0);
        seg->handle = random();
+       if (seg->handle == DSM_HANDLE_INVALID)  /* Reserve sentinel */
+           continue;
        if (dsm_impl_op(DSM_OP_CREATE, seg->handle, size, &seg->impl_private,
                        &seg->mapped_address, &seg->mapped_size, ERROR))
            break;
index 8be7c9aeeb567718bf1addae5138e2a7e6f20211..bc91be62131fcc38a90724ec91f54e0294539291 100644 (file)
@@ -19,6 +19,9 @@ typedef struct dsm_segment dsm_segment;
 
 #define DSM_CREATE_NULL_IF_MAXSEGMENTS         0x0001
 
+/* A sentinel value for an invalid DSM handle. */
+#define DSM_HANDLE_INVALID 0
+
 /* Startup and shutdown functions. */
 struct PGShmemHeader;          /* avoid including pg_shmem.h */
 extern void dsm_cleanup_using_control_segment(dsm_handle old_control_handle);