Substantial rewrite of async.c to avoid problems with non-reentrant stdio

and possibly other problems.  Minor changes in xact.c and postgres.c's
main loop to support new handling of async NOTIFY.
This commit is contained in:
Tom Lane 1998-10-06 02:40:09 +00:00
parent e7e027a6c9
commit c77a29a14e
7 changed files with 651 additions and 517 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.23 1998/09/01 04:27:19 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.24 1998/10/06 02:39:58 tgl Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
@ -901,6 +901,9 @@ CommitTransaction()
/* handle commit for large objects [ PA, 7/17/98 ] */ /* handle commit for large objects [ PA, 7/17/98 ] */
_lo_commit(); _lo_commit();
/* NOTIFY commit must also come before lower-level cleanup */
AtCommit_Notify();
CloseSequences(); CloseSequences();
DestroyTempRels(); DestroyTempRels();
AtEOXact_portals(); AtEOXact_portals();
@ -916,10 +919,6 @@ CommitTransaction()
* ---------------- * ----------------
*/ */
s->state = TRANS_DEFAULT; s->state = TRANS_DEFAULT;
{ /* want this after commit */
if (IsNormalProcessingMode())
Async_NotifyAtCommit();
}
/* /*
* Let others to know about no transaction in progress - vadim * Let others to know about no transaction in progress - vadim
@ -967,6 +966,7 @@ AbortTransaction()
* do abort processing * do abort processing
* ---------------- * ----------------
*/ */
AtAbort_Notify();
CloseSequences(); CloseSequences();
AtEOXact_portals(); AtEOXact_portals();
RecordTransactionAbort(); RecordTransactionAbort();
@ -982,17 +982,6 @@ AbortTransaction()
* ---------------- * ----------------
*/ */
s->state = TRANS_DEFAULT; s->state = TRANS_DEFAULT;
{
/*
* We need to do this in case another process notified us while we
* are in the middle of an aborted transaction. We need to notify
* our frontend after we finish the current transaction. -- jw,
* 1/3/94
*/
if (IsNormalProcessingMode())
Async_NotifyAtAbort();
}
} }
/* -------------------------------- /* --------------------------------
@ -1455,6 +1444,30 @@ UserAbortTransactionBlock()
s->blockState = TBLOCK_ENDABORT; s->blockState = TBLOCK_ENDABORT;
} }
/* --------------------------------
* AbortOutOfAnyTransaction
*
* This routine is provided for error recovery purposes. It aborts any
* active transaction or transaction block, leaving the system in a known
* idle state.
* --------------------------------
*/
void
AbortOutOfAnyTransaction()
{
TransactionState s = CurrentTransactionState;
/*
* Get out of any low-level transaction
*/
if (s->state != TRANS_DEFAULT)
AbortTransaction();
/*
* Now reset the high-level state
*/
s->blockState = TBLOCK_DEFAULT;
}
bool bool
IsTransactionBlock() IsTransactionBlock()
{ {

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.90 1998/10/02 01:14:14 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.91 1998/10/06 02:40:01 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
@ -1511,7 +1511,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.90 $ $Date: 1998/10/02 01:14:14 $\n"); puts("$Revision: 1.91 $ $Date: 1998/10/06 02:40:01 $\n");
} }
/* ---------------- /* ----------------
@ -1559,7 +1559,16 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
ReadyForQuery(whereToSendOutput); ReadyForQuery(whereToSendOutput);
/* ---------------- /* ----------------
* (2) read a command. * (2) deal with pending asynchronous NOTIFY from other backends,
* and enable async.c's signal handler to execute NOTIFY directly.
* ----------------
*/
QueryCancel = false; /* forget any earlier CANCEL signal */
EnableNotifyInterrupt();
/* ----------------
* (3) read a command.
* ---------------- * ----------------
*/ */
MemSet(parser_input, 0, MAX_PARSE_BUFFER); MemSet(parser_input, 0, MAX_PARSE_BUFFER);
@ -1569,7 +1578,13 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
QueryCancel = false; /* forget any earlier CANCEL signal */ QueryCancel = false; /* forget any earlier CANCEL signal */
/* ---------------- /* ----------------
* (3) process the command. * (4) disable async.c's signal handler.
* ----------------
*/
DisableNotifyInterrupt();
/* ----------------
* (5) process the command.
* ---------------- * ----------------
*/ */
switch (firstchar) switch (firstchar)
@ -1640,7 +1655,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
} }
/* ---------------- /* ----------------
* (4) commit the current transaction * (6) commit the current transaction
* *
* Note: if we had an empty input buffer, then we didn't * Note: if we had an empty input buffer, then we didn't
* call pg_exec_query, so we don't bother to commit this transaction. * call pg_exec_query, so we don't bother to commit this transaction.

View File

@ -70,10 +70,6 @@ static char *opt_names[] = {
"syslog", /* use syslog for error messages */ "syslog", /* use syslog for error messages */
"hostlookup", /* enable hostname lookup in ps_status */ "hostlookup", /* enable hostname lookup in ps_status */
"showportnumber", /* show port number in ps_status */ "showportnumber", /* show port number in ps_status */
"notifyunlock", /* enable unlock of pg_listener after
* notify */
"notifyhack" /* enable notify hack to remove duplicate
* tuples */
}; };
/* /*

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: xact.h,v 1.15 1998/09/01 04:34:35 momjian Exp $ * $Id: xact.h,v 1.16 1998/10/06 02:40:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -107,6 +107,7 @@ extern void BeginTransactionBlock(void);
extern void EndTransactionBlock(void); extern void EndTransactionBlock(void);
extern bool IsTransactionBlock(void); extern bool IsTransactionBlock(void);
extern void UserAbortTransactionBlock(void); extern void UserAbortTransactionBlock(void);
extern void AbortOutOfAnyTransaction(void);
extern TransactionId DisabledTransactionId; extern TransactionId DisabledTransactionId;

View File

@ -1,27 +1,38 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* async.h-- * async.h--
* * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN
*
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: async.h,v 1.9 1998/09/01 04:35:22 momjian Exp $ * $Id: async.h,v 1.10 1998/10/06 02:40:08 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef ASYNC_H #ifndef ASYNC_H
#define ASYNC_H #define ASYNC_H
#include <nodes/memnodes.h> #include <postgres.h>
extern void Async_NotifyHandler(SIGNAL_ARGS); /* notify-related SQL statements */
extern void Async_Notify(char *relname); extern void Async_Notify(char *relname);
extern void Async_NotifyAtCommit(void);
extern void Async_NotifyAtAbort(void);
extern void Async_Listen(char *relname, int pid); extern void Async_Listen(char *relname, int pid);
extern void Async_Unlisten(char *relname, int pid); extern void Async_Unlisten(char *relname, int pid);
extern GlobalMemory notifyContext; /* perform (or cancel) outbound notify processing at transaction commit */
extern void AtCommit_Notify(void);
extern void AtAbort_Notify(void);
/* signal handler for inbound notifies (SIGUSR2) */
extern void Async_NotifyHandler(SIGNAL_ARGS);
/*
* enable/disable processing of inbound notifies directly from signal handler.
* The enable routine first performs processing of any inbound notifies that
* have occurred since the last disable. These are meant to be called ONLY
* from the appropriate places in PostgresMain().
*/
extern void EnableNotifyInterrupt(void);
extern void DisableNotifyInterrupt(void);
#endif /* ASYNC_H */ #endif /* ASYNC_H */

View File

@ -66,10 +66,6 @@ enum pg_option_enum
OPT_SYSLOG, /* use syslog for error messages */ OPT_SYSLOG, /* use syslog for error messages */
OPT_HOSTLOOKUP, /* enable hostname lookup in ps_status */ OPT_HOSTLOOKUP, /* enable hostname lookup in ps_status */
OPT_SHOWPORTNUMBER, /* show port number in ps_status */ OPT_SHOWPORTNUMBER, /* show port number in ps_status */
OPT_NOTIFYUNLOCK, /* enable unlock of pg_listener after
* notify */
OPT_NOTIFYHACK, /* enable notify hack to remove duplicate
* tuples */
NUM_PG_OPTIONS /* must be the last item of enum */ NUM_PG_OPTIONS /* must be the last item of enum */
}; };