*
  *      Doxygen documentation root for Veil
  *
- *      Copyright (c) 2005 - 2016 Marc Munro
+ *      Copyright (c) 2005 - 2018 Marc Munro
  *      Author:  Marc Munro
  * License: BSD
  *
 */
 /*! \page History History and Compatibility
 \section past Changes History
+\subsection v10_3 Version 10.3.0 (Stable) (2018-05-04)
+This version supports PostgreSQL V10.3.
+
+This was updated following a report of being unable to build veil for
+Postgres 10.3.  This was the result of changes made in postgres after
+version 9.5, to change the way that LWlocks are handled.  This version
+of veil may work for earlier versions of Postgres 10.x but has not been
+tested.
+
 \subsection v9_5 Version 9.5.0 (Stable) (2016-03-14)
 This version supports PostgreSQL V9.5.
 
 <TABLE>
   <TR>
     <TD rowspan=2>Veil version</TD>
-    <TD colspan=5>Postgres Version</TD>
+    <TD colspan=7>Postgres Version</TD>
   </TR>
   <TR>
     <TD>9.1</TD>
     <TD>9.3</TD>
     <TD>9.4</TD>
     <TD>9.5</TD>
+    <TD>10.x (x < 3)</TD>
+    <TD>10.3</TD>
   </TR>
   <TR>
     <TD>9.1.0 (Stable)</TD>
     <TD>- </TD>
     <TD>- </TD>
     <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
   </TR>
   <TR>
     <TD>9.2.0 (Stable)</TD>
     <TD>- </TD>
     <TD>- </TD>
     <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
   </TR>
   <TR>
     <TD>9.3.0 (Stable)</TD>
     <TD>Yes</TD>
     <TD>- </TD>
     <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
   </TR>
   <TR>
     <TD>9.4.1 (Stable)</TD>
     <TD>- </TD>
     <TD>Yes</TD>
     <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
   </TR>
   <TR>
     <TD>9.5.0 (Stable)</TD>
     <TD>- </TD>
     <TD>- </TD>
     <TD>Yes</TD>
+    <TD>- </TD>
+    <TD>- </TD>
+  </TR>
+  <TR>
+    <TD>10.3 (Stable)</TD>
+    <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
+    <TD>- </TD>
+    <TD>? </TD>
+    <TD>Yes</TD>
   </TR>
 </TABLE>
 
 
  * @file   veil_shmem.c
  * \code
  *     Author:       Marc Munro
- *     Copyright (c) 2005 - 2015 Marc Munro
+ *     Copyright (c) 2005 - 2018 Marc Munro
  *     License:      BSD
  *
  * \endcode
  *  - We look up variable "x" in the current hash, and if we have to
  *    allocate space for it, allocate it from the current context.
  *
- * Note that We use a dynamicall allocated LWLock, VeilLWLock to protect
+ * Note that We use a dynamically allocated LWLock, VeilLWLock to protect
  * our shared control structures.
  * 
  */
  */
 #define OTHER_CONTEXT(x)   (x ? 0: 1)
 
+/**
+ * The MemContext that we use to manage our tranche of LWLocks
+ */
+static MemContext *lwlock_context;
+
+/**
+ * Name of tranche of LWLocks used by veil.
+ */
+static char *TRANCHE_NAME = "veil";
+
+/**
+ * Return the next LWLock from our tranche.
+ * Note that locking is the responsibility of the caller.
+ */
+static LWLock *
+NextLWLock()
+{
+   // TODO: Ensure we don't exceed the number of locks in our tranche
+   if (lwlock_context->lwlock_idx > 0) {
+       lwlock_context->lwlock_idx--;
+   }
+   else {
+       // Error
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("veil: out of LWLocks")));
+   }
+   return
+       &(lwlock_context->lwlock_tranche[lwlock_context->lwlock_idx].lock);
+}
+
+
 /** 
  * Veil's startup function.  This should be run when the Veil shared
  * library is loaded by postgres.
    /* Request a Veil-specific shared memory context */
    RequestAddinShmemSpace(2 * veil_shmem_context_size() * veil_dbs);
 
-   /* Request a LWLock for later use by all backends */
-   RequestAddinLWLocks(veil_dbs);
+   /* Request LWLocks for later use by all backends */
+   RequestNamedLWLockTranche(TRANCHE_NAME, veil_dbs);
 }
 
 /** 
            context->next = sizeof(MemContext);
            context->limit = size;
            context->lwlock = VeilLWLock;
+
+           if (i == 0) {
+               /* This context is the very first MemContext for the
+                * cluster: this is the one used to manage our LWLocks
+                * tranche. */
+               context->lwlock_tranche = GetNamedLWLockTranche(TRANCHE_NAME);
+               context->lwlock_idx = max_dbs;
+               lwlock_context = context;
+           }
            return context;
        }
    }
 }
 
 
+
 /** 
  * Attach to, creating and initialising as necessary, the shared memory
  * control structure.  Record this for the session in shared_meminfo.
            else {
                /* Allocate new LWLock for this new shared memory
                 * context */
-               VeilLWLock = LWLockAssign(); 
+               VeilLWLock = NextLWLock(); 
            }
            /* Record the lock id in context0 (for possible re-use if
             * the current database is dropped and a new veil-using
 
  * @file   veil_shmem.h
  * \code
  *     Author:       Marc Munro
- *     Copyright (c) 2005 - 2011 Marc Munro
+ *     Copyright (c) 2005 - 2018 Marc Munro
  *     License:      BSD
  * 
  * \endcode
                                   * which this context was created,
                                   * or by which it has been taken
                                   * over. */
-   LWLockId  lwlock;             /**< The LWLock associated with this
+   LWLock   *lwlock;             /**< The LWLock associated with this
                                   *  memory context */
    size_t    next;               /**< Offset of 1st free byte */
    size_t    limit;              /**< Offset, of 1st byte beyond this 
                                   * struct */
-   
+   LWLockPadded *lwlock_tranche; /**< A tranche of lwlocks (only used in
+                                  * the zeroth MemContext. */
+   int           lwlock_idx;     /**< Index into the above. */
    struct ShmemCtl *memctl;      /**< Pointer to shared memory control
                                   * structure. */
     void     *memory[0];          /**< The rest of the chunk, from which