Don't include low level locking code from frontend code.

Some frontend code like e.g. pg_xlogdump or pg_resetxlog, has to use
backend headers. Unfortunately until now that code includes most of the
locking code. It's generally not nice to expose such low level details,
but de6fd1c898 made that a hard problem. We fall back to defining
'inline' away if the compiler doesn't support it - that can cause linker
errors like on buildfarm animal pademelon if a inline function
references backend only code.

To fix that problem separate definitions from lock.h that are required
from frontend code into lockdefs.h and use it in the relevant
places. I've only removed the minimal amount of necessary definitions
for now - it might turn out that we want more for other reasons.

To avoid such details being exposed again put some checks against being
included from frontend code into atomics.h, lock.h, lwlock.h and
s_lock.h. It's otherwise fairly easy to indirectly include these
headers.

Discussion: 20150806070902.GE12214@awork2.anarazel.de
This commit is contained in:
Andres Freund 2015-08-07 15:10:56 +02:00
parent 18e8613564
commit 4eda0a6470
12 changed files with 80 additions and 43 deletions

View File

@ -22,6 +22,7 @@
#include "postgres.h"
#include "access/hash.h"
#include "utils/hsearch.h"
/*

View File

@ -17,7 +17,7 @@
#include "access/sdir.h"
#include "access/skey.h"
#include "nodes/tidbitmap.h"
#include "storage/lock.h"
#include "storage/lockdefs.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"

View File

@ -24,7 +24,7 @@
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "storage/bufmgr.h"
#include "storage/lock.h"
#include "storage/lockdefs.h"
#include "utils/relcache.h"
/*

View File

@ -14,8 +14,8 @@
#define TUPTOASTER_H
#include "access/htup_details.h"
#include "storage/lockdefs.h"
#include "utils/relcache.h"
#include "storage/lock.h"
/*
* This enables de-toasting of index entries. Needed until VACUUM is

View File

@ -14,7 +14,7 @@
#define OBJECTADDRESS_H
#include "nodes/pg_list.h"
#include "storage/lock.h"
#include "storage/lockdefs.h"
#include "utils/acl.h"
#include "utils/relcache.h"

View File

@ -37,6 +37,10 @@
#ifndef ATOMICS_H
#define ATOMICS_H
#ifdef FRONTEND
#error "atomics.h may not be included from frontend code"
#endif
#define INSIDE_ATOMICS_H
#include <limits.h>

View File

@ -14,6 +14,11 @@
#ifndef LOCK_H_
#define LOCK_H_
#ifdef FRONTEND
#error "lock.h may not be included from frontend code"
#endif
#include "storage/lockdefs.h"
#include "storage/backendid.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
@ -77,15 +82,6 @@ typedef struct
((vxid).backendId = (proc).backendId, \
(vxid).localTransactionId = (proc).lxid)
/*
* LOCKMODE is an integer (1..N) indicating a lock type. LOCKMASK is a bit
* mask indicating a set of held or requested lock types (the bit 1<<mode
* corresponds to a particular lock mode).
*/
typedef int LOCKMASK;
typedef int LOCKMODE;
/* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
#define MAX_LOCKMODES 10
@ -133,28 +129,6 @@ typedef uint16 LOCKMETHODID;
#define DEFAULT_LOCKMETHOD 1
#define USER_LOCKMETHOD 2
/*
* These are the valid values of type LOCKMODE for all the standard lock
* methods (both DEFAULT and USER).
*/
/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
#define NoLock 0
#define AccessShareLock 1 /* SELECT */
#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */
#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE
* INDEX CONCURRENTLY */
#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */
#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW
* SHARE */
#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR
* UPDATE */
#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM
* FULL, and unqualified LOCK TABLE */
/*
* LOCKTAG is the key information needed to look up a LOCK item in the
* lock hashtable. A LOCKTAG value uniquely identifies a lockable object.
@ -536,13 +510,6 @@ extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
extern Size LockShmemSize(void);
extern LockData *GetLockStatusData(void);
typedef struct xl_standby_lock
{
TransactionId xid; /* xid of holder of AccessExclusiveLock */
Oid dbOid;
Oid relOid;
} xl_standby_lock;
extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);

View File

@ -0,0 +1,56 @@
/*-------------------------------------------------------------------------
*
* lockdefs.h
* Frontend exposed parts of postgres' low level lock mechanism
*
* The split between lockdefs.h and lock.h is not very principled. This file
* contains definition that have to (indirectly) be available when included by
* FRONTEND code.
*
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/storage/lockdefs.h
*
*-------------------------------------------------------------------------
*/
#ifndef LOCKDEFS_H_
#define LOCKDEFS_H_
/*
* LOCKMODE is an integer (1..N) indicating a lock type. LOCKMASK is a bit
* mask indicating a set of held or requested lock types (the bit 1<<mode
* corresponds to a particular lock mode).
*/
typedef int LOCKMASK;
typedef int LOCKMODE;
/*
* These are the valid values of type LOCKMODE for all the standard lock
* methods (both DEFAULT and USER).
*/
/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
#define NoLock 0
#define AccessShareLock 1 /* SELECT */
#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */
#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE
* INDEX CONCURRENTLY */
#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */
#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW
* SHARE */
#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR
* UPDATE */
#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM
* FULL, and unqualified LOCK TABLE */
typedef struct xl_standby_lock
{
TransactionId xid; /* xid of holder of AccessExclusiveLock */
Oid dbOid;
Oid relOid;
} xl_standby_lock;
#endif /* LOCKDEF_H_ */

View File

@ -14,6 +14,10 @@
#ifndef LWLOCK_H
#define LWLOCK_H
#ifdef FRONTEND
#error "lwlock.h may not be included from frontend code"
#endif
#include "lib/ilist.h"
#include "storage/s_lock.h"
#include "port/atomics.h"

View File

@ -14,6 +14,7 @@
#ifndef PROCARRAY_H
#define PROCARRAY_H
#include "storage/lock.h"
#include "storage/standby.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"

View File

@ -96,6 +96,10 @@
#ifndef S_LOCK_H
#define S_LOCK_H
#ifdef FRONTEND
#error "s_lock.h may not be included from frontend code"
#endif
#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)

View File

@ -16,7 +16,7 @@
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
#include "storage/lock.h"
#include "storage/lockdefs.h"
#include "storage/procsignal.h"
#include "storage/relfilenode.h"