Fix code that doesn't work on machines with strict alignment requirements:

must use memcpy here rather than struct assignment.

In passing, rearrange some randomly-ordered declarations to be a tad less
random.
This commit is contained in:
Tom Lane 2010-04-20 22:55:03 +00:00
parent 481cb5d9b5
commit 7de2dfccc5
1 changed files with 33 additions and 32 deletions

View File

@ -29,7 +29,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/replication/walreceiver.c,v 1.9 2010/04/19 14:10:45 mha Exp $ * $PostgreSQL: pgsql/src/backend/replication/walreceiver.c,v 1.10 2010/04/20 22:55:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -76,9 +76,15 @@ static uint32 recvOff = 0;
static volatile sig_atomic_t got_SIGHUP = false; static volatile sig_atomic_t got_SIGHUP = false;
static volatile sig_atomic_t got_SIGTERM = false; static volatile sig_atomic_t got_SIGTERM = false;
static void ProcessWalRcvInterrupts(void); /*
static void EnableWalRcvImmediateExit(void); * LogstreamResult indicates the byte positions that we have already
static void DisableWalRcvImmediateExit(void); * written/fsynced.
*/
static struct
{
XLogRecPtr Write; /* last byte + 1 written out in the standby */
XLogRecPtr Flush; /* last byte + 1 flushed in the standby */
} LogstreamResult;
/* /*
* About SIGTERM handling: * About SIGTERM handling:
@ -98,6 +104,21 @@ static void DisableWalRcvImmediateExit(void);
*/ */
static volatile bool WalRcvImmediateInterruptOK = false; static volatile bool WalRcvImmediateInterruptOK = false;
/* Prototypes for private functions */
static void ProcessWalRcvInterrupts(void);
static void EnableWalRcvImmediateExit(void);
static void DisableWalRcvImmediateExit(void);
static void WalRcvDie(int code, Datum arg);
static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
static void XLogWalRcvFlush(void);
/* Signal handlers */
static void WalRcvSigHupHandler(SIGNAL_ARGS);
static void WalRcvShutdownHandler(SIGNAL_ARGS);
static void WalRcvQuickDieHandler(SIGNAL_ARGS);
static void static void
ProcessWalRcvInterrupts(void) ProcessWalRcvInterrupts(void)
{ {
@ -118,47 +139,25 @@ ProcessWalRcvInterrupts(void)
} }
static void static void
EnableWalRcvImmediateExit() EnableWalRcvImmediateExit(void)
{ {
WalRcvImmediateInterruptOK = true; WalRcvImmediateInterruptOK = true;
ProcessWalRcvInterrupts(); ProcessWalRcvInterrupts();
} }
static void static void
DisableWalRcvImmediateExit() DisableWalRcvImmediateExit(void)
{ {
WalRcvImmediateInterruptOK = false; WalRcvImmediateInterruptOK = false;
ProcessWalRcvInterrupts(); ProcessWalRcvInterrupts();
} }
/* Signal handlers */
static void WalRcvSigHupHandler(SIGNAL_ARGS);
static void WalRcvShutdownHandler(SIGNAL_ARGS);
static void WalRcvQuickDieHandler(SIGNAL_ARGS);
/* Prototypes for private functions */
static void WalRcvDie(int code, Datum arg);
static void XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len);
static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
static void XLogWalRcvFlush(void);
/*
* LogstreamResult indicates the byte positions that we have already
* written/fsynced.
*/
static struct
{
XLogRecPtr Write; /* last byte + 1 written out in the standby */
XLogRecPtr Flush; /* last byte + 1 flushed in the standby */
} LogstreamResult;
/* Main entry point for walreceiver process */ /* Main entry point for walreceiver process */
void void
WalReceiverMain(void) WalReceiverMain(void)
{ {
char conninfo[MAXCONNINFO]; char conninfo[MAXCONNINFO];
XLogRecPtr startpoint; XLogRecPtr startpoint;
/* use volatile pointer to prevent code rearrangement */ /* use volatile pointer to prevent code rearrangement */
volatile WalRcvData *walrcv = WalRcv; volatile WalRcvData *walrcv = WalRcv;
@ -398,18 +397,20 @@ XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len)
if (len < sizeof(XLogRecPtr)) if (len < sizeof(XLogRecPtr))
ereport(ERROR, ereport(ERROR,
(errmsg("invalid WAL message received from primary"))); (errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg_internal("invalid WAL message received from primary")));
recptr = *((XLogRecPtr *) buf); memcpy(&recptr, buf, sizeof(XLogRecPtr));
buf += sizeof(XLogRecPtr); buf += sizeof(XLogRecPtr);
len -= sizeof(XLogRecPtr); len -= sizeof(XLogRecPtr);
XLogWalRcvWrite(buf, len, recptr); XLogWalRcvWrite(buf, len, recptr);
break; break;
} }
default: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION), (errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid replication message type %d", errmsg_internal("invalid replication message type %d",
type))); type)));
} }
} }