Use AllocateFile(), FreeFile() and palloc() rather than fopen(), fclose()

and malloc() in pgstat.c, respectively. This simplifies error recovery,
as well as being more consistent with the rest of the backend.
This commit is contained in:
Neil Conway 2004-10-28 01:38:41 +00:00
parent e6f9bf9b7f
commit 6f1b3cf19c

View File

@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2004, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.83 2004/10/25 06:27:21 neilc Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.84 2004/10/28 01:38:41 neilc Exp $
* ----------
*/
#include "postgres.h"
@ -42,6 +42,7 @@
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "storage/backendid.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
@ -682,7 +683,7 @@ pgstat_bestart(void)
/* ----------
* pgstat_report_activity() -
*
* Called in tcop/postgres.c to tell the collector what the backend
* Called from tcop/postgres.c to tell the collector what the backend
* is actually doing (usually "<IDLE>" or the start of the query to
* be executed).
* ----------
@ -988,7 +989,7 @@ pgstat_ping(void)
/*
* Create or enlarge the pgStatTabstatMessages array
*/
static bool
static void
more_tabstat_space(void)
{
PgStat_MsgTabstat *newMessages;
@ -998,39 +999,25 @@ more_tabstat_space(void)
/* Create (another) quantum of message buffers */
newMessages = (PgStat_MsgTabstat *)
malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
if (newMessages == NULL)
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
MemoryContextAllocZero(TopMemoryContext,
sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
/* Create or enlarge the pointer array */
if (pgStatTabstatMessages == NULL)
msgArray = (PgStat_MsgTabstat **)
malloc(sizeof(PgStat_MsgTabstat *) * newAlloc);
MemoryContextAlloc(TopMemoryContext,
sizeof(PgStat_MsgTabstat *) * newAlloc);
else
msgArray = (PgStat_MsgTabstat **)
realloc(pgStatTabstatMessages,
sizeof(PgStat_MsgTabstat *) * newAlloc);
if (msgArray == NULL)
{
free(newMessages);
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
repalloc(pgStatTabstatMessages,
sizeof(PgStat_MsgTabstat *) * newAlloc);
MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[pgStatTabstatAlloc + i] = newMessages++;
pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = newAlloc;
return true;
Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
}
/* ----------
@ -1102,14 +1089,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
* If we ran out of message buffers, we just allocate more.
*/
if (pgStatTabstatUsed >= pgStatTabstatAlloc)
{
if (!more_tabstat_space())
{
stats->no_stats = TRUE;
return;
}
Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
}
more_tabstat_space();
/*
* Use the first entry of the next message buffer.
@ -1146,10 +1126,8 @@ pgstat_count_xact_commit(void)
* new xact-counters.
*/
if (pgStatTabstatAlloc == 0)
{
if (!more_tabstat_space())
return;
}
more_tabstat_space();
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
@ -1180,10 +1158,8 @@ pgstat_count_xact_rollback(void)
* new xact-counters.
*/
if (pgStatTabstatAlloc == 0)
{
if (!more_tabstat_space())
return;
}
more_tabstat_space();
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
@ -1529,13 +1505,8 @@ PgstatCollectorMain(int argc, char *argv[])
/*
* Create the known backends table
*/
pgStatBeTable = (PgStat_StatBeEntry *) malloc(
pgStatBeTable = (PgStat_StatBeEntry *) palloc0(
sizeof(PgStat_StatBeEntry) * MaxBackends);
if (pgStatBeTable == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory in statistics collector --- abort")));
memset(pgStatBeTable, 0, sizeof(PgStat_StatBeEntry) * MaxBackends);
readPipe = pgStatPipe[0];
@ -1804,11 +1775,7 @@ pgstat_recvbuffer(void)
/*
* Allocate the message buffer
*/
msgbuffer = (char *) malloc(PGSTAT_RECVBUFFERSZ);
if (msgbuffer == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory in statistics collector --- abort")));
msgbuffer = (char *) palloc(PGSTAT_RECVBUFFERSZ);
/*
* Loop forever
@ -2416,7 +2383,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* simply return zero for anything and the collector simply starts
* from scratch with empty counters.
*/
if ((fpin = fopen(pgStat_fname, PG_BINARY_R)) == NULL)
if ((fpin = AllocateFile(pgStat_fname, PG_BINARY_R)) == NULL)
return;
/*
@ -2437,8 +2404,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
/*
@ -2450,7 +2416,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
&found);
if (dbentry == NULL)
{
fclose(fpin);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
@ -2459,8 +2424,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
memcpy(dbentry, &dbbuf, sizeof(PgStat_StatDBEntry));
@ -2479,19 +2443,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
hash_ctl.hash = tag_hash;
hash_ctl.hcxt = use_mcxt;
PG_TRY();
{
dbentry->tables = hash_create("Per-database table",
PGSTAT_TAB_HASH_SIZE,
&hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
}
PG_CATCH();
{
fclose(fpin);
PG_RE_THROW();
}
PG_END_TRY();
dbentry->tables = hash_create("Per-database table",
PGSTAT_TAB_HASH_SIZE,
&hash_ctl,
HASH_ELEM | HASH_FUNCTION | mcxt_flags);
/*
* Arrange that following 'T's add entries to this
@ -2515,8 +2470,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
/*
@ -2529,19 +2483,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
(void *) &tabbuf.tableid,
HASH_ENTER, &found);
if (tabentry == NULL)
{
fclose(fpin);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
}
if (found)
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
memcpy(tabentry, &tabbuf, sizeof(tabbuf));
@ -2552,30 +2502,23 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
*/
case 'M':
if (betab == NULL || numbackends == NULL)
{
fclose(fpin);
return;
}
goto done;
if (fread(&maxbackends, 1, sizeof(maxbackends), fpin) !=
sizeof(maxbackends))
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
if (maxbackends == 0)
{
fclose(fpin);
return;
}
goto done;
/*
* Allocate space (in TopTransactionContext too) for the
* backend table.
*/
if (use_mcxt == NULL)
*betab = (PgStat_StatBeEntry *) malloc(
*betab = (PgStat_StatBeEntry *) palloc(
sizeof(PgStat_StatBeEntry) * maxbackends);
else
*betab = (PgStat_StatBeEntry *) MemoryContextAlloc(
@ -2587,16 +2530,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
* 'B' A PgStat_StatBeEntry follows.
*/
case 'B':
if (betab == NULL || numbackends == NULL)
{
fclose(fpin);
return;
}
if (*betab == NULL)
{
fclose(fpin);
return;
}
if (betab == NULL || numbackends == NULL || *betab == NULL)
goto done;
/*
* Read it directly into the table.
@ -2607,8 +2542,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
{
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
/*
@ -2624,28 +2558,25 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
if (numbackends != 0)
*numbackends = havebackends;
if (havebackends >= maxbackends)
{
fclose(fpin);
return;
}
goto done;
break;
/*
* 'E' The EOF marker of a complete stats file.
*/
case 'E':
fclose(fpin);
return;
goto done;
default:
ereport(pgStatRunningInCollector ? LOG : WARNING,
(errmsg("corrupted pgstat.stat file")));
fclose(fpin);
return;
goto done;
}
}
fclose(fpin);
done:
FreeFile(fpin);
}
/*