66 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
9- * src/include /storage/shm_toc.c
9+ * src/backend /storage/ipc /shm_toc.c
1010 *
1111 *-------------------------------------------------------------------------
1212 */
2020typedef struct shm_toc_entry
2121{
2222 uint64 key ; /* Arbitrary identifier */
23- uint64 offset ; /* Bytes offset */
23+ Size offset ; /* Offset, in bytes, from TOC start */
2424} shm_toc_entry ;
2525
2626struct shm_toc
2727{
28- uint64 toc_magic ; /* Magic number for this TOC */
28+ uint64 toc_magic ; /* Magic number identifying this TOC */
2929 slock_t toc_mutex ; /* Spinlock for mutual exclusion */
3030 Size toc_total_bytes ; /* Bytes managed by this TOC */
3131 Size toc_allocated_bytes ; /* Bytes allocated of those managed */
32- Size toc_nentry ; /* Number of entries in TOC */
32+ uint32 toc_nentry ; /* Number of entries in TOC */
3333 shm_toc_entry toc_entry [FLEXIBLE_ARRAY_MEMBER ];
3434};
3535
@@ -53,7 +53,7 @@ shm_toc_create(uint64 magic, void *address, Size nbytes)
5353
5454/*
5555 * Attach to an existing table of contents. If the magic number found at
56- * the target address doesn't match our expectations, returns NULL.
56+ * the target address doesn't match our expectations, return NULL.
5757 */
5858extern shm_toc *
5959shm_toc_attach (uint64 magic , void * address )
@@ -64,7 +64,7 @@ shm_toc_attach(uint64 magic, void *address)
6464 return NULL ;
6565
6666 Assert (toc -> toc_total_bytes >= toc -> toc_allocated_bytes );
67- Assert (toc -> toc_total_bytes >= offsetof(shm_toc , toc_entry ));
67+ Assert (toc -> toc_total_bytes > offsetof(shm_toc , toc_entry ));
6868
6969 return toc ;
7070}
@@ -76,7 +76,7 @@ shm_toc_attach(uint64 magic, void *address)
7676 * just a way of dividing a single physical shared memory segment into logical
7777 * chunks that may be used for different purposes.
7878 *
79- * We allocated backwards from the end of the segment, so that the TOC entries
79+ * We allocate backwards from the end of the segment, so that the TOC entries
8080 * can grow forward from the start of the segment.
8181 */
8282extern void *
@@ -140,7 +140,7 @@ shm_toc_freespace(shm_toc *toc)
140140/*
141141 * Insert a TOC entry.
142142 *
143- * The idea here is that process setting up the shared memory segment will
143+ * The idea here is that the process setting up the shared memory segment will
144144 * register the addresses of data structures within the segment using this
145145 * function. Each data structure will be identified using a 64-bit key, which
146146 * is assumed to be a well-known or discoverable integer. Other processes
@@ -155,17 +155,17 @@ shm_toc_freespace(shm_toc *toc)
155155 * data structure here. But the real idea here is just to give someone mapping
156156 * a dynamic shared memory the ability to find the bare minimum number of
157157 * pointers that they need to bootstrap. If you're storing a lot of stuff in
158- * here , you're doing it wrong.
158+ * the TOC , you're doing it wrong.
159159 */
160160void
161161shm_toc_insert (shm_toc * toc , uint64 key , void * address )
162162{
163163 volatile shm_toc * vtoc = toc ;
164- uint64 total_bytes ;
165- uint64 allocated_bytes ;
166- uint64 nentry ;
167- uint64 toc_bytes ;
168- uint64 offset ;
164+ Size total_bytes ;
165+ Size allocated_bytes ;
166+ Size nentry ;
167+ Size toc_bytes ;
168+ Size offset ;
169169
170170 /* Relativize pointer. */
171171 Assert (address > (void * ) toc );
@@ -181,7 +181,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
181181
182182 /* Check for memory exhaustion and overflow. */
183183 if (toc_bytes + sizeof (shm_toc_entry ) > total_bytes ||
184- toc_bytes + sizeof (shm_toc_entry ) < toc_bytes )
184+ toc_bytes + sizeof (shm_toc_entry ) < toc_bytes ||
185+ nentry >= PG_UINT32_MAX )
185186 {
186187 SpinLockRelease (& toc -> toc_mutex );
187188 ereport (ERROR ,
@@ -220,10 +221,13 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
220221void *
221222shm_toc_lookup (shm_toc * toc , uint64 key , bool noError )
222223{
223- uint64 nentry ;
224- uint64 i ;
224+ uint32 nentry ;
225+ uint32 i ;
225226
226- /* Read the number of entries before we examine any entry. */
227+ /*
228+ * Read the number of entries before we examine any entry. We assume that
229+ * reading a uint32 is atomic.
230+ */
227231 nentry = toc -> toc_nentry ;
228232 pg_read_barrier ();
229233
0 commit comments