• Tom Lane's avatar
    Make the different Unix-y semaphore implementations ABI-compatible. · be7b2848
    Tom Lane authored
    Previously, the "sem" field of PGPROC varied in size depending on which
    kernel semaphore API we were using.  That was okay as long as there was
    only one likely choice per platform, but in the wake of commit ecb0d20a,
    that assumption seems rather shaky.  It doesn't seem out of the question
    anymore that an extension compiled against one API choice might be loaded
    into a postmaster built with another choice.  Moreover, this prevents any
    possibility of selecting the semaphore API at postmaster startup, which
    might be something we want to do in future.
    
    Hence, change PGPROC.sem to be PGSemaphore (i.e. a pointer) for all Unix
    semaphore APIs, and turn the pointed-to data into an opaque struct whose
    contents are only known within the responsible modules.
    
    For the SysV and unnamed-POSIX APIs, the pointed-to data has to be
    allocated elsewhere in shared memory, which takes a little bit of
    rejiggering of the InitShmemAllocation code sequence.  (I invented a
    ShmemAllocUnlocked() function to make that a little cleaner than it used
    to be.  That function is not meant for any uses other than the ones it
    has now, but it beats having InitShmemAllocation() know explicitly about
    allocation of space for semaphores and spinlocks.)  This change means an
    extra indirection to access the semaphore data, but since we only touch
    that when blocking or awakening a process, there shouldn't be any
    meaningful performance penalty.  Moreover, at least for the unnamed-POSIX
    case on Linux, the sem_t type is quite a bit wider than a pointer, so this
    reduces sizeof(PGPROC) which seems like a good thing.
    
    For the named-POSIX API, there's effectively no change: the PGPROC.sem
    field was and still is a pointer to something returned by sem_open() in
    the postmaster's memory space.  Document and check the pre-existing
    limitation that this case can't work in EXEC_BACKEND mode.
    
    It did not seem worth unifying the Windows semaphore ABI with the Unix
    cases, since there's no likelihood of needing ABI compatibility much less
    runtime switching across those cases.  However, we can simplify the Windows
    code a bit if we define PGSemaphore as being directly a HANDLE, rather than
    pointer to HANDLE, so let's do that while we're here.  (This also ends up
    being no change in what's physically stored in PGPROC.sem.  We're just
    moving the HANDLE fetch from callees to callers.)
    
    It would take a bunch of additional code shuffling to get to the point of
    actually choosing a semaphore API at postmaster start, but the effects
    of that would now be localized in the port/XXX_sema.c files, so it seems
    like fit material for a separate patch.  The need for it is unproven as
    yet, anyhow, whereas the ABI risk to extensions seems real enough.
    
    Discussion: https://postgr.es/m/4029.1481413370@sss.pgh.pa.us
    be7b2848
lwlock.c 52.3 KB