Skip to content

Commit cd00406

Browse files
committed
Replace time_t with pg_time_t (same values, but always int64) in on-disk
data structures and backend internal APIs. This solves problems we've seen recently with inconsistent layout of pg_control between machines that have 32-bit time_t and those that have already migrated to 64-bit time_t. Also, we can get out from under the problem that Windows' Unix-API emulation is not consistent about the width of time_t. There are a few remaining places where local time_t variables are used to hold the current or recent result of time(NULL). I didn't bother changing these since they do not affect any cross-module APIs and surely all platforms will have 64-bit time_t before overflow becomes an actual risk. time_t should be avoided for anything visible to extension modules, however.
1 parent ee7a677 commit cd00406

File tree

17 files changed

+98
-91
lines changed

17 files changed

+98
-91
lines changed

contrib/pgcrypto/internal.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2727
* SUCH DAMAGE.
2828
*
29-
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.27 2007/11/15 21:14:31 momjian Exp $
29+
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.28 2008/02/17 02:09:26 tgl Exp $
3030
*/
3131

3232
#include "postgres.h"
@@ -649,7 +649,8 @@ system_reseed(void)
649649
skip = 1;
650650
else if ((t - seed_time) > SYSTEM_RESEED_MAX)
651651
skip = 0;
652-
else if (!check_time || (t - check_time) > SYSTEM_RESEED_CHECK_TIME)
652+
else if (check_time == 0 ||
653+
(t - check_time) > SYSTEM_RESEED_CHECK_TIME)
653654
{
654655
check_time = t;
655656

src/backend/access/transam/xlog.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.292 2008/01/21 11:17:46 petere Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.293 2008/02/17 02:09:27 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -271,7 +271,7 @@ typedef struct XLogCtlWrite
271271
{
272272
XLogwrtResult LogwrtResult; /* current value of LogwrtResult */
273273
int curridx; /* cache index of next block to write */
274-
time_t lastSegSwitchTime; /* time of last xlog segment switch */
274+
pg_time_t lastSegSwitchTime; /* time of last xlog segment switch */
275275
} XLogCtlWrite;
276276

277277
/*
@@ -1553,7 +1553,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
15531553
if (XLogArchivingActive())
15541554
XLogArchiveNotifySeg(openLogId, openLogSeg);
15551555

1556-
Write->lastSegSwitchTime = time(NULL);
1556+
Write->lastSegSwitchTime = (pg_time_t) time(NULL);
15571557

15581558
/*
15591559
* Signal bgwriter to start a checkpoint if we've consumed too
@@ -4217,7 +4217,7 @@ BootStrapXLOG(void)
42174217
checkPoint.nextOid = FirstBootstrapObjectId;
42184218
checkPoint.nextMulti = FirstMultiXactId;
42194219
checkPoint.nextMultiOffset = 0;
4220-
checkPoint.time = time(NULL);
4220+
checkPoint.time = (pg_time_t) time(NULL);
42214221

42224222
ShmemVariableCache->nextXid = checkPoint.nextXid;
42234223
ShmemVariableCache->nextOid = checkPoint.nextOid;
@@ -4972,7 +4972,7 @@ StartupXLOG(void)
49724972
ControlFile->checkPointCopy = checkPoint;
49734973
if (minRecoveryLoc.xlogid != 0 || minRecoveryLoc.xrecoff != 0)
49744974
ControlFile->minRecoveryPoint = minRecoveryLoc;
4975-
ControlFile->time = time(NULL);
4975+
ControlFile->time = (pg_time_t) time(NULL);
49764976
UpdateControlFile();
49774977

49784978
/*
@@ -5277,7 +5277,7 @@ StartupXLOG(void)
52775277
InRecovery = false;
52785278

52795279
ControlFile->state = DB_IN_PRODUCTION;
5280-
ControlFile->time = time(NULL);
5280+
ControlFile->time = (pg_time_t) time(NULL);
52815281
UpdateControlFile();
52825282

52835283
/* start the archive_timeout timer running */
@@ -5496,10 +5496,10 @@ GetInsertRecPtr(void)
54965496
/*
54975497
* Get the time of the last xlog segment switch
54985498
*/
5499-
time_t
5499+
pg_time_t
55005500
GetLastSegSwitchTime(void)
55015501
{
5502-
time_t result;
5502+
pg_time_t result;
55035503

55045504
/* Need WALWriteLock, but shared lock is sufficient */
55055505
LWLockAcquire(WALWriteLock, LW_SHARED);
@@ -5676,7 +5676,7 @@ CreateCheckPoint(int flags)
56765676
if (shutdown)
56775677
{
56785678
ControlFile->state = DB_SHUTDOWNING;
5679-
ControlFile->time = time(NULL);
5679+
ControlFile->time = (pg_time_t) time(NULL);
56805680
UpdateControlFile();
56815681
}
56825682

@@ -5690,7 +5690,7 @@ CreateCheckPoint(int flags)
56905690
/* Begin filling in the checkpoint WAL record */
56915691
MemSet(&checkPoint, 0, sizeof(checkPoint));
56925692
checkPoint.ThisTimeLineID = ThisTimeLineID;
5693-
checkPoint.time = time(NULL);
5693+
checkPoint.time = (pg_time_t) time(NULL);
56945694

56955695
/*
56965696
* We must hold WALInsertLock while examining insert state to determine
@@ -5891,7 +5891,7 @@ CreateCheckPoint(int flags)
58915891
ControlFile->prevCheckPoint = ControlFile->checkPoint;
58925892
ControlFile->checkPoint = ProcLastRecPtr;
58935893
ControlFile->checkPointCopy = checkPoint;
5894-
ControlFile->time = time(NULL);
5894+
ControlFile->time = (pg_time_t) time(NULL);
58955895
UpdateControlFile();
58965896
LWLockRelease(ControlFileLock);
58975897

@@ -5992,7 +5992,7 @@ RecoveryRestartPoint(const CheckPoint *checkPoint)
59925992
* Checking true elapsed time keeps us from doing restartpoints too often
59935993
* while rapidly scanning large amounts of WAL.
59945994
*/
5995-
elapsed_secs = time(NULL) - ControlFile->time;
5995+
elapsed_secs = (pg_time_t) time(NULL) - ControlFile->time;
59965996
if (elapsed_secs < CheckPointTimeout / 2)
59975997
return;
59985998

@@ -6028,7 +6028,7 @@ RecoveryRestartPoint(const CheckPoint *checkPoint)
60286028
ControlFile->prevCheckPoint = ControlFile->checkPoint;
60296029
ControlFile->checkPoint = ReadRecPtr;
60306030
ControlFile->checkPointCopy = *checkPoint;
6031-
ControlFile->time = time(NULL);
6031+
ControlFile->time = (pg_time_t) time(NULL);
60326032
UpdateControlFile();
60336033

60346034
ereport((recoveryLogRestartpoints ? LOG : DEBUG2),

src/backend/postmaster/bgwriter.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.48 2008/01/01 19:45:51 momjian Exp $
40+
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.49 2008/02/17 02:09:27 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -163,12 +163,12 @@ static bool am_bg_writer = false;
163163
static bool ckpt_active = false;
164164

165165
/* these values are valid when ckpt_active is true: */
166-
static time_t ckpt_start_time;
166+
static pg_time_t ckpt_start_time;
167167
static XLogRecPtr ckpt_start_recptr;
168168
static double ckpt_cached_elapsed;
169169

170-
static time_t last_checkpoint_time;
171-
static time_t last_xlog_switch_time;
170+
static pg_time_t last_checkpoint_time;
171+
static pg_time_t last_xlog_switch_time;
172172

173173
/* Prototypes for private functions */
174174

@@ -250,7 +250,7 @@ BackgroundWriterMain(void)
250250
/*
251251
* Initialize so that first time-driven event happens at the correct time.
252252
*/
253-
last_checkpoint_time = last_xlog_switch_time = time(NULL);
253+
last_checkpoint_time = last_xlog_switch_time = (pg_time_t) time(NULL);
254254

255255
/*
256256
* Create a resource owner to keep track of our resources (currently only
@@ -361,7 +361,7 @@ BackgroundWriterMain(void)
361361
{
362362
bool do_checkpoint = false;
363363
int flags = 0;
364-
time_t now;
364+
pg_time_t now;
365365
int elapsed_secs;
366366

367367
/*
@@ -407,7 +407,7 @@ BackgroundWriterMain(void)
407407
* occurs without an external request, but we set the CAUSE_TIME flag
408408
* bit even if there is also an external request.
409409
*/
410-
now = time(NULL);
410+
now = (pg_time_t) time(NULL);
411411
elapsed_secs = now - last_checkpoint_time;
412412
if (elapsed_secs >= CheckPointTimeout)
413413
{
@@ -504,13 +504,13 @@ BackgroundWriterMain(void)
504504
static void
505505
CheckArchiveTimeout(void)
506506
{
507-
time_t now;
508-
time_t last_time;
507+
pg_time_t now;
508+
pg_time_t last_time;
509509

510510
if (XLogArchiveTimeout <= 0)
511511
return;
512512

513-
now = time(NULL);
513+
now = (pg_time_t) time(NULL);
514514

515515
/* First we do a quick check using possibly-stale local state. */
516516
if ((int) (now - last_xlog_switch_time) < XLogArchiveTimeout)
@@ -730,7 +730,7 @@ IsCheckpointOnSchedule(double progress)
730730
* Check progress against time elapsed and checkpoint_timeout.
731731
*/
732732
gettimeofday(&now, NULL);
733-
elapsed_time = ((double) (now.tv_sec - ckpt_start_time) +
733+
elapsed_time = ((double) ((pg_time_t) now.tv_sec - ckpt_start_time) +
734734
now.tv_usec / 1000000.0) / CheckPointTimeout;
735735

736736
if (progress < elapsed_time)

src/backend/postmaster/syslogger.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.44 2008/01/25 20:42:10 tgl Exp $
21+
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.45 2008/02/17 02:09:27 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -331,7 +331,7 @@ SysLoggerMain(int argc, char *argv[])
331331
if (!rotation_requested && Log_RotationAge > 0)
332332
{
333333
/* Do a logfile rotation if it's time */
334-
pg_time_t now = time(NULL);
334+
pg_time_t now = (pg_time_t) time(NULL);
335335

336336
if (now >= next_rotation_time)
337337
rotation_requested = time_based_rotation = true;

src/backend/utils/adt/date.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.138 2008/01/01 19:45:52 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.139 2008/02/17 02:09:28 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -945,8 +945,10 @@ tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result)
945945

946946
/* time2tm()
947947
* Convert time data type to POSIX time structure.
948-
* For dates within the system-supported time_t range, convert to the
949-
* local time zone. If out of this range, leave as GMT. - tgl 97/05/27
948+
*
949+
* For dates within the range of pg_time_t, convert to the local time zone.
950+
* If out of this range, leave as UTC (in practice that could only happen
951+
* if pg_time_t is just 32 bits) - thomas 97/05/27
950952
*/
951953
static int
952954
time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec)
@@ -2466,10 +2468,9 @@ timetz_zone(PG_FUNCTION_ARGS)
24662468
if (tzp)
24672469
{
24682470
/* Get the offset-from-GMT that is valid today for the selected zone */
2469-
pg_time_t now;
2471+
pg_time_t now = (pg_time_t) time(NULL);
24702472
struct pg_tm *tm;
24712473

2472-
now = time(NULL);
24732474
tm = pg_localtime(&now, tzp);
24742475
tz = -tm->tm_gmtoff;
24752476
}

src/backend/utils/adt/datetime.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.184 2008/01/01 19:45:52 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.185 2008/02/17 02:09:28 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -650,9 +650,11 @@ ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
650650
* "20011225T040506.789-07"
651651
*
652652
* Use the system-provided functions to get the current time zone
653-
* if not specified in the input string.
654-
* If the date is outside the time_t system-supported time range,
655-
* then assume UTC time zone. - thomas 1997-05-27
653+
* if not specified in the input string.
654+
*
655+
* If the date is outside the range of pg_time_t (in practice that could only
656+
* happen if pg_time_t is just 32 bits), then assume UTC time zone - thomas
657+
* 1997-05-27
656658
*/
657659
int
658660
DecodeDateTime(char **field, int *ftype, int nf,

src/backend/utils/adt/nabstime.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.152 2008/01/01 19:45:52 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.153 2008/02/17 02:09:28 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -86,6 +86,8 @@ static void parsetinterval(char *i_string,
8686
* GetCurrentAbsoluteTime()
8787
*
8888
* Get the current system time (relative to Unix epoch).
89+
*
90+
* NB: this will overflow in 2038; it should be gone long before that.
8991
*/
9092
AbsoluteTime
9193
GetCurrentAbsoluteTime(void)
@@ -1029,12 +1031,7 @@ tintervalrel(PG_FUNCTION_ARGS)
10291031
Datum
10301032
timenow(PG_FUNCTION_ARGS)
10311033
{
1032-
time_t sec;
1033-
1034-
if (time(&sec) < 0)
1035-
PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
1036-
1037-
PG_RETURN_ABSOLUTETIME((AbsoluteTime) sec);
1034+
PG_RETURN_ABSOLUTETIME(GetCurrentAbsoluteTime());
10381035
}
10391036

10401037
/*

src/backend/utils/adt/timestamp.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.184 2008/01/01 19:45:52 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.185 2008/02/17 02:09:28 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1264,9 +1264,14 @@ TimestampDifferenceExceeds(TimestampTz start_time,
12641264
*
12651265
* We do not use time_t internally in Postgres, but this is provided for use
12661266
* by functions that need to interpret, say, a stat(2) result.
1267+
*
1268+
* To avoid having the function's ABI vary depending on the width of time_t,
1269+
* we declare the argument as pg_time_t, which is cast-compatible with
1270+
* time_t but always 64 bits wide (unless the platform has no 64-bit type).
1271+
* This detail should be invisible to callers, at least at source code level.
12671272
*/
12681273
TimestampTz
1269-
time_t_to_timestamptz(time_t tm)
1274+
time_t_to_timestamptz(pg_time_t tm)
12701275
{
12711276
TimestampTz result;
12721277

@@ -1284,17 +1289,22 @@ time_t_to_timestamptz(time_t tm)
12841289
* Convert a TimestampTz to time_t.
12851290
*
12861291
* This too is just marginally useful, but some places need it.
1292+
*
1293+
* To avoid having the function's ABI vary depending on the width of time_t,
1294+
* we declare the result as pg_time_t, which is cast-compatible with
1295+
* time_t but always 64 bits wide (unless the platform has no 64-bit type).
1296+
* This detail should be invisible to callers, at least at source code level.
12871297
*/
1288-
time_t
1298+
pg_time_t
12891299
timestamptz_to_time_t(TimestampTz t)
12901300
{
1291-
time_t result;
1301+
pg_time_t result;
12921302

12931303
#ifdef HAVE_INT64_TIMESTAMP
1294-
result = (time_t) (t / USECS_PER_SEC +
1304+
result = (pg_time_t) (t / USECS_PER_SEC +
12951305
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
12961306
#else
1297-
result = (time_t) (t +
1307+
result = (pg_time_t) (t +
12981308
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
12991309
#endif
13001310

src/backend/utils/init/globals.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.104 2008/01/01 19:45:53 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.105 2008/02/17 02:09:29 tgl Exp $
1212
*
1313
* NOTES
1414
* Globals used all over the place should be declared here and not
@@ -33,7 +33,7 @@ volatile uint32 InterruptHoldoffCount = 0;
3333
volatile uint32 CritSectionCount = 0;
3434

3535
int MyProcPid;
36-
time_t MyStartTime;
36+
pg_time_t MyStartTime;
3737
struct Port *MyProcPort;
3838
long MyCancelKey;
3939

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy