Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit961ad3f

Browse files
committed
On Windows, syslogger runs in two threads. The main thread processes config
reload and rotation signals, and a helper thread reads messages from thepipe and writes them to the log file. However, server code isn't generallythread-safe, so if both try to do e.g palloc()/pfree() at the same time,bad things will happen. To fix that, use a critical section (which is likea mutex) to enforce that only one the threads are active at a time.
1 parent78974cf commit961ad3f

File tree

1 file changed

+28
-33
lines changed

1 file changed

+28
-33
lines changed

‎src/backend/postmaster/syslogger.c

Lines changed: 28 additions & 33 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.56 2010/04/01 20:12:22 heikki Exp $
21+
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.57 2010/04/16 09:51:49 heikki Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -117,7 +117,7 @@ HANDLEsyslogPipe[2] = {0, 0};
117117

118118
#ifdefWIN32
119119
staticHANDLEthreadHandle=0;
120-
staticCRITICAL_SECTIONsysfileSection;
120+
staticCRITICAL_SECTIONsysloggerSection;
121121
#endif
122122

123123
/*
@@ -268,7 +268,8 @@ SysLoggerMain(int argc, char *argv[])
268268

269269
#ifdefWIN32
270270
/* Fire up separate data transfer thread */
271-
InitializeCriticalSection(&sysfileSection);
271+
InitializeCriticalSection(&sysloggerSection);
272+
EnterCriticalSection(&sysloggerSection);
272273

273274
threadHandle= (HANDLE)_beginthreadex(NULL,0,pipeThread,NULL,0,NULL);
274275
if (threadHandle==0)
@@ -423,8 +424,16 @@ SysLoggerMain(int argc, char *argv[])
423424
* On Windows we leave it to a separate thread to transfer data and
424425
* detect pipe EOF. The main thread just wakes up once a second to
425426
* check for SIGHUP and rotation conditions.
427+
*
428+
* Server code isn't generally thread-safe, so we ensure that only
429+
* one of the threads is active at a time by entering the critical
430+
* section whenever we're not sleeping.
426431
*/
432+
LeaveCriticalSection(&sysloggerSection);
433+
427434
pg_usleep(1000000L);
435+
436+
EnterCriticalSection(&sysloggerSection);
428437
#endif/* WIN32 */
429438

430439
if (pipe_eof_seen)
@@ -911,17 +920,9 @@ write_syslogger_file(const char *buffer, int count, int destination)
911920
if (destination==LOG_DESTINATION_CSVLOG&&csvlogFile==NULL)
912921
open_csvlogfile();
913922

914-
#ifdefWIN32
915-
EnterCriticalSection(&sysfileSection);
916-
#endif
917-
918923
logfile=destination==LOG_DESTINATION_CSVLOG ?csvlogFile :syslogFile;
919924
rc=fwrite(buffer,1,count,logfile);
920925

921-
#ifdefWIN32
922-
LeaveCriticalSection(&sysfileSection);
923-
#endif
924-
925926
/* can't use ereport here because of possible recursion */
926927
if (rc!=count)
927928
write_stderr("could not write to log file: %s\n",strerror(errno));
@@ -945,11 +946,21 @@ pipeThread(void *arg)
945946
for (;;)
946947
{
947948
DWORDbytesRead;
949+
BOOLresult;
950+
951+
result=ReadFile(syslogPipe[0],
952+
logbuffer+bytes_in_logbuffer,
953+
sizeof(logbuffer)-bytes_in_logbuffer,
954+
&bytesRead,0);
948955

949-
if (!ReadFile(syslogPipe[0],
950-
logbuffer+bytes_in_logbuffer,
951-
sizeof(logbuffer)-bytes_in_logbuffer,
952-
&bytesRead,0))
956+
/*
957+
* Enter critical section before doing anything that might touch
958+
* global state shared by the main thread. Anything that uses
959+
* palloc()/pfree() in particular are not safe outside the critical
960+
* section.
961+
*/
962+
EnterCriticalSection(&sysloggerSection);
963+
if (!result)
953964
{
954965
DWORDerror=GetLastError();
955966

@@ -966,6 +977,7 @@ pipeThread(void *arg)
966977
bytes_in_logbuffer+=bytesRead;
967978
process_pipe_input(logbuffer,&bytes_in_logbuffer);
968979
}
980+
LeaveCriticalSection(&sysloggerSection);
969981
}
970982

971983
/* We exit the above loop only upon detecting pipe EOF */
@@ -974,6 +986,7 @@ pipeThread(void *arg)
974986
/* if there's any data left then force it out now */
975987
flush_pipe_input(logbuffer,&bytes_in_logbuffer);
976988

989+
LeaveCriticalSection(&sysloggerSection);
977990
_endthread();
978991
return0;
979992
}
@@ -1097,18 +1110,9 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
10971110
_setmode(_fileno(fh),_O_TEXT);/* use CRLF line endings on Windows */
10981111
#endif
10991112

1100-
/* On Windows, need to interlock against data-transfer thread */
1101-
#ifdefWIN32
1102-
EnterCriticalSection(&sysfileSection);
1103-
#endif
1104-
11051113
fclose(syslogFile);
11061114
syslogFile=fh;
11071115

1108-
#ifdefWIN32
1109-
LeaveCriticalSection(&sysfileSection);
1110-
#endif
1111-
11121116
/* instead of pfree'ing filename, remember it for next time */
11131117
if (last_file_name!=NULL)
11141118
pfree(last_file_name);
@@ -1164,18 +1168,9 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for)
11641168
_setmode(_fileno(fh),_O_TEXT);/* use CRLF line endings on Windows */
11651169
#endif
11661170

1167-
/* On Windows, need to interlock against data-transfer thread */
1168-
#ifdefWIN32
1169-
EnterCriticalSection(&sysfileSection);
1170-
#endif
1171-
11721171
fclose(csvlogFile);
11731172
csvlogFile=fh;
11741173

1175-
#ifdefWIN32
1176-
LeaveCriticalSection(&sysfileSection);
1177-
#endif
1178-
11791174
/* instead of pfree'ing filename, remember it for next time */
11801175
if (last_csv_file_name!=NULL)
11811176
pfree(last_csv_file_name);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp