Deadlock ceallnup.
(void) change for aix and hp compilers. protocol cleanup.
This commit is contained in:
parent
f49d41353d
commit
b4564a98fa
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.8 1998/01/20 22:11:55 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.9 1998/01/27 15:34:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -728,7 +728,7 @@ func_get_detail(char *funcname,
|
|||||||
funcname);
|
funcname);
|
||||||
elog(NOTICE, "that satisfies the given argument types. you will have to");
|
elog(NOTICE, "that satisfies the given argument types. you will have to");
|
||||||
elog(NOTICE, "retype your query using explicit typecasts.");
|
elog(NOTICE, "retype your query using explicit typecasts.");
|
||||||
func_error("func_get_detail", funcname, nargs, oid_array);
|
func_error("", funcname, nargs, oid_array);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -758,7 +758,7 @@ func_get_detail(char *funcname,
|
|||||||
elog(ERROR, "no such attribute or function \"%s\"",
|
elog(ERROR, "no such attribute or function \"%s\"",
|
||||||
funcname);
|
funcname);
|
||||||
}
|
}
|
||||||
func_error("func_get_detail", funcname, nargs, oid_array);
|
func_error("", funcname, nargs, oid_array);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.71 1998/01/27 03:11:46 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.72 1998/01/27 15:34:43 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -473,7 +473,7 @@ pmdaemonize(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (fork())
|
if (fork())
|
||||||
exit(0);
|
_exit(0);
|
||||||
/* GH: If there's no setsid(), we hopefully don't need silent mode.
|
/* GH: If there's no setsid(), we hopefully don't need silent mode.
|
||||||
* Until there's a better solution.
|
* Until there's a better solution.
|
||||||
*/
|
*/
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.22 1998/01/27 03:00:28 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.23 1998/01/27 15:34:49 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Outside modules can create a lock table and acquire/release
|
* Outside modules can create a lock table and acquire/release
|
||||||
* locks. A lock table is a shared memory hash table. When
|
* locks. A lock table is a shared memory hash table. When
|
||||||
* a process tries to acquire a lock of a type that conflicts
|
* a process tries to acquire a lock of a type that conflictRs
|
||||||
* with existing locks, it is put to sleep using the routines
|
* with existing locks, it is put to sleep using the routines
|
||||||
* in storage/lmgr/proc.c.
|
* in storage/lmgr/proc.c.
|
||||||
*
|
*
|
||||||
@ -39,6 +39,7 @@
|
|||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "storage/shmem.h"
|
#include "storage/shmem.h"
|
||||||
|
#include "storage/sinvaladt.h"
|
||||||
#include "storage/spin.h"
|
#include "storage/spin.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "storage/lock.h"
|
#include "storage/lock.h"
|
||||||
@ -1415,7 +1416,8 @@ LockingDisabled()
|
|||||||
*
|
*
|
||||||
* This code takes a list of locks a process holds, and the lock that
|
* This code takes a list of locks a process holds, and the lock that
|
||||||
* the process is sleeping on, and tries to find if any of the processes
|
* the process is sleeping on, and tries to find if any of the processes
|
||||||
* waiting on its locks hold the lock it is waiting for.
|
* waiting on its locks hold the lock it is waiting for. If no deadlock
|
||||||
|
* is found, it goes on to look at all the processes waiting on their locks.
|
||||||
*
|
*
|
||||||
* We have already locked the master lock before being called.
|
* We have already locked the master lock before being called.
|
||||||
*/
|
*/
|
||||||
@ -1427,6 +1429,15 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
|
|||||||
XIDLookupEnt *tmp = NULL;
|
XIDLookupEnt *tmp = NULL;
|
||||||
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
|
||||||
LOCK *lock;
|
LOCK *lock;
|
||||||
|
static PROC* checked_procs[MaxBackendId];
|
||||||
|
static int nprocs;
|
||||||
|
|
||||||
|
if (skip_check)
|
||||||
|
{
|
||||||
|
/* initialize at start of recursion */
|
||||||
|
checked_procs[0] = MyProc;
|
||||||
|
nprocs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (SHMQueueEmpty(lockQueue))
|
if (SHMQueueEmpty(lockQueue))
|
||||||
return false;
|
return false;
|
||||||
@ -1457,18 +1468,29 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
|
|||||||
*/
|
*/
|
||||||
if (lock == findlock && !skip_check)
|
if (lock == findlock && !skip_check)
|
||||||
return true;
|
return true;
|
||||||
else if (lock != findlock || !skip_check)
|
|
||||||
|
/*
|
||||||
|
* No sense in looking at the wait queue of the lock we are
|
||||||
|
* looking for as it is MyProc's lock entry.
|
||||||
|
* If lock == findlock, and I got here, skip_check must be true.
|
||||||
|
*/
|
||||||
|
if (lock != findlock)
|
||||||
{
|
{
|
||||||
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
PROC_QUEUE *waitQueue = &(lock->waitProcs);
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
proc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
proc = (PROC *) MAKE_PTR(waitQueue->links.prev);
|
||||||
for (i = 0; i < waitQueue->size; i++)
|
for (i = 0; i < waitQueue->size; i++)
|
||||||
{
|
{
|
||||||
/* prevent endless loops */
|
for (j = 0; j < nprocs; j++)
|
||||||
if (proc != MyProc && skip_check)
|
if (checked_procs[j] == proc)
|
||||||
|
break;
|
||||||
|
if (j >= nprocs)
|
||||||
{
|
{
|
||||||
|
checked_procs[nprocs++] = proc;
|
||||||
|
Assert(nprocs <= MaxBackendId);
|
||||||
/* If we found a deadlock, we can stop right now */
|
/* If we found a deadlock, we can stop right now */
|
||||||
if (DeadLockCheck(&(proc->lockQueue), findlock, false))
|
if (DeadLockCheck(&(proc->lockQueue), findlock, false))
|
||||||
return true;
|
return true;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: heapam.h,v 1.24 1998/01/25 05:04:21 scrappy Exp $
|
* $Id: heapam.h,v 1.25 1998/01/27 15:35:18 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -101,10 +101,10 @@ typedef HeapAccessStatisticsData *HeapAccessStatistics;
|
|||||||
#define heap_getattr(tup, b, attnum, tupleDesc, isnull) \
|
#define heap_getattr(tup, b, attnum, tupleDesc, isnull) \
|
||||||
(AssertMacro((tup) != NULL) ? \
|
(AssertMacro((tup) != NULL) ? \
|
||||||
((attnum) > (int) (tup)->t_natts) ? \
|
((attnum) > (int) (tup)->t_natts) ? \
|
||||||
(((isnull) ? (*(isnull) = true) : (void)NULL), (Datum)NULL) : \
|
(((isnull) ? (*(isnull) = true) : dummyretNULL), (Datum)NULL) : \
|
||||||
((attnum) > 0) ? \
|
((attnum) > 0) ? \
|
||||||
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) : \
|
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) : \
|
||||||
(((isnull) ? (*(isnull) = false) : (void)NULL), heap_getsysattr((tup), (b), (attnum))) : \
|
(((isnull) ? (*(isnull) = false) : dummyretNULL), heap_getsysattr((tup), (b), (attnum))) : \
|
||||||
(Datum)NULL)
|
(Datum)NULL)
|
||||||
|
|
||||||
extern HeapAccessStatistics heap_access_stats; /* in stats.c */
|
extern HeapAccessStatistics heap_access_stats; /* in stats.c */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: c.h,v 1.29 1998/01/26 01:41:49 scrappy Exp $
|
* $Id: c.h,v 1.30 1998/01/27 15:35:00 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -181,8 +181,18 @@ typedef char *Pointer;
|
|||||||
|
|
||||||
#endif /* !HAVE_ANSI_CPP */
|
#endif /* !HAVE_ANSI_CPP */
|
||||||
|
|
||||||
|
#ifndef __GNUC__ /* GNU cc */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __GNUC__ /* GNU cc */
|
#ifndef __GNUC__ /* GNU cc */
|
||||||
#define inline
|
#define inline
|
||||||
|
/*
|
||||||
|
* dummyret is used to set return values in macros that use ?: to make
|
||||||
|
* assignments. gcc wants these to be void, other compilers like char
|
||||||
|
*/
|
||||||
|
#define dummyret char
|
||||||
|
#else
|
||||||
|
#define dummyret void
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NEED_STD_HDRS)
|
#if defined(NEED_STD_HDRS)
|
||||||
@ -693,7 +703,7 @@ typedef struct Exception
|
|||||||
*/
|
*/
|
||||||
/* we do this so if the macro is used in an if action, it will work */
|
/* we do this so if the macro is used in an if action, it will work */
|
||||||
#define StrNCpy(dst,src,len) \
|
#define StrNCpy(dst,src,len) \
|
||||||
(strncpy((dst),(src),(len)),(len > 0) ? *((dst)+(len)-1)='\0' : (void)NULL,(void)(dst))
|
(strncpy((dst),(src),(len)),(len > 0) ? *((dst)+(len)-1)='\0' : (dummyret)NULL,(void)(dst))
|
||||||
|
|
||||||
/* Get a bit mask of the bits set in non-int32 aligned addresses */
|
/* Get a bit mask of the bits set in non-int32 aligned addresses */
|
||||||
#define INT_ALIGN_MASK (sizeof(int32) - 1)
|
#define INT_ALIGN_MASK (sizeof(int32) - 1)
|
||||||
|
@ -216,8 +216,6 @@ extern void srandom(int seed);
|
|||||||
* number of seconds.
|
* number of seconds.
|
||||||
* We don't check for deadlocks just before sleeping because a deadlock is
|
* We don't check for deadlocks just before sleeping because a deadlock is
|
||||||
* a rare event, and checking is an expensive operation.
|
* a rare event, and checking is an expensive operation.
|
||||||
* We only detect deadlocks between two processes, not three or more, but
|
|
||||||
* these are the most common.
|
|
||||||
*/
|
*/
|
||||||
#define DEADLOCK_CHECK_TIMER 60
|
#define DEADLOCK_CHECK_TIMER 60
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pqcomm.h,v 1.20 1998/01/27 04:08:28 momjian Exp $
|
* $Id: pqcomm.h,v 1.21 1998/01/27 15:35:22 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -35,8 +35,12 @@ typedef union SockAddr {
|
|||||||
|
|
||||||
#define UNIXSOCK_PATH(sun,port) \
|
#define UNIXSOCK_PATH(sun,port) \
|
||||||
(sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)) + \
|
(sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)) + \
|
||||||
sizeof ((sun).sun_len) + sizeof ((sun).sun_family))
|
+ 1 + sizeof ((sun).sun_family))
|
||||||
|
/*
|
||||||
|
* + 1 is for BSD-specific sizeof((sun).sun_len)
|
||||||
|
* We never actually set sun_len, and I can't think of a
|
||||||
|
* platform-safe way of doing it, but the code still works. bjm
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These manipulate the frontend/backend protocol version number.
|
* These manipulate the frontend/backend protocol version number.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.\" This is -*-nroff-*-
|
.\" This is -*-nroff-*-
|
||||||
.\" XXX standard disclaimer belongs here....
|
.\" XXX standard disclaimer belongs here....
|
||||||
.\" $Header: /cvsroot/pgsql/src/man/Attic/lock.l,v 1.1 1998/01/23 06:01:36 momjian Exp $
|
.\" $Header: /cvsroot/pgsql/src/man/Attic/lock.l,v 1.2 1998/01/27 15:35:30 momjian Exp $
|
||||||
.TH FETCH SQL 01/23/93 PostgreSQL PostgreSQL
|
.TH FETCH SQL 01/23/93 PostgreSQL PostgreSQL
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lock - exclusive lock a table
|
lock - exclusive lock a table
|
||||||
@ -17,6 +17,12 @@ inside a transaction. If you don't exclusive lock the table before the
|
|||||||
and do their own \fBupdate\fP, causing a deadlock while you both wait
|
and do their own \fBupdate\fP, causing a deadlock while you both wait
|
||||||
for the other to release the \fBselect\fP-induced shared lock so you can
|
for the other to release the \fBselect\fP-induced shared lock so you can
|
||||||
get an exclusive lock to do the \fBupdate.\fP
|
get an exclusive lock to do the \fBupdate.\fP
|
||||||
|
.PP
|
||||||
|
Another example of deadlock is where one user locks one table, and
|
||||||
|
another user locks a second table. While both keep their existing
|
||||||
|
locks, the first user tries to lock the second user's table, and the
|
||||||
|
second user tries to lock the first user's table. Both users deadlock
|
||||||
|
waiting for the tables to become available.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.nf
|
.nf
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user