*** pgsql/src/backend/postmaster/syslogger.c 2010/04/01 20:12:28 1.51.2.2 --- pgsql/src/backend/postmaster/syslogger.c 2010/04/16 09:51:54 1.51.2.3 *************** *** 18,24 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.51.2.1 2009/11/19 02:45:40 tgl Exp $ * *------------------------------------------------------------------------- */ --- 18,24 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.51.2.2 2010/04/01 20:12:28 heikki Exp $ * *------------------------------------------------------------------------- */ *************** HANDLE syslogPipe[2] = {0, 0}; *** 117,123 **** #ifdef WIN32 static HANDLE threadHandle = 0; ! static CRITICAL_SECTION sysfileSection; #endif /* --- 117,123 ---- #ifdef WIN32 static HANDLE threadHandle = 0; ! static CRITICAL_SECTION sysloggerSection; #endif /* *************** SysLoggerMain(int argc, char *argv[]) *** 268,274 **** #ifdef WIN32 /* Fire up separate data transfer thread */ ! InitializeCriticalSection(&sysfileSection); threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL); if (threadHandle == 0) --- 268,275 ---- #ifdef WIN32 /* Fire up separate data transfer thread */ ! InitializeCriticalSection(&sysloggerSection); ! EnterCriticalSection(&sysloggerSection); threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL); if (threadHandle == 0) *************** SysLoggerMain(int argc, char *argv[]) *** 423,430 **** --- 424,439 ---- * On Windows we leave it to a separate thread to transfer data and * detect pipe EOF. The main thread just wakes up once a second to * check for SIGHUP and rotation conditions. + * + * Server code isn't generally thread-safe, so we ensure that only + * one of the threads is active at a time by entering the critical + * section whenever we're not sleeping. */ + LeaveCriticalSection(&sysloggerSection); + pg_usleep(1000000L); + + EnterCriticalSection(&sysloggerSection); #endif /* WIN32 */ if (pipe_eof_seen) *************** write_syslogger_file(const char *buffer, *** 911,927 **** if (destination == LOG_DESTINATION_CSVLOG && csvlogFile == NULL) open_csvlogfile(); - #ifdef WIN32 - EnterCriticalSection(&sysfileSection); - #endif - logfile = destination == LOG_DESTINATION_CSVLOG ? csvlogFile : syslogFile; rc = fwrite(buffer, 1, count, logfile); - #ifdef WIN32 - LeaveCriticalSection(&sysfileSection); - #endif - /* can't use ereport here because of possible recursion */ if (rc != count) write_stderr("could not write to log file: %s\n", strerror(errno)); --- 920,928 ---- *************** pipeThread(void *arg) *** 945,955 **** for (;;) { DWORD bytesRead; ! if (!ReadFile(syslogPipe[0], ! logbuffer + bytes_in_logbuffer, ! sizeof(logbuffer) - bytes_in_logbuffer, ! &bytesRead, 0)) { DWORD error = GetLastError(); --- 946,966 ---- for (;;) { DWORD bytesRead; + BOOL result; + + result = ReadFile(syslogPipe[0], + logbuffer + bytes_in_logbuffer, + sizeof(logbuffer) - bytes_in_logbuffer, + &bytesRead, 0); ! /* ! * Enter critical section before doing anything that might touch ! * global state shared by the main thread. Anything that uses ! * palloc()/pfree() in particular are not safe outside the critical ! * section. ! */ ! EnterCriticalSection(&sysloggerSection); ! if (!result) { DWORD error = GetLastError(); *************** pipeThread(void *arg) *** 966,971 **** --- 977,983 ---- bytes_in_logbuffer += bytesRead; process_pipe_input(logbuffer, &bytes_in_logbuffer); } + LeaveCriticalSection(&sysloggerSection); } /* We exit the above loop only upon detecting pipe EOF */ *************** pipeThread(void *arg) *** 974,979 **** --- 986,992 ---- /* if there's any data left then force it out now */ flush_pipe_input(logbuffer, &bytes_in_logbuffer); + LeaveCriticalSection(&sysloggerSection); _endthread(); return 0; } *************** logfile_rotate(bool time_based_rotation, *** 1097,1114 **** _setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */ #endif - /* On Windows, need to interlock against data-transfer thread */ - #ifdef WIN32 - EnterCriticalSection(&sysfileSection); - #endif - fclose(syslogFile); syslogFile = fh; - #ifdef WIN32 - LeaveCriticalSection(&sysfileSection); - #endif - /* instead of pfree'ing filename, remember it for next time */ if (last_file_name != NULL) pfree(last_file_name); --- 1110,1118 ---- *************** logfile_rotate(bool time_based_rotation, *** 1164,1181 **** _setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */ #endif - /* On Windows, need to interlock against data-transfer thread */ - #ifdef WIN32 - EnterCriticalSection(&sysfileSection); - #endif - fclose(csvlogFile); csvlogFile = fh; - #ifdef WIN32 - LeaveCriticalSection(&sysfileSection); - #endif - /* instead of pfree'ing filename, remember it for next time */ if (last_csv_file_name != NULL) pfree(last_csv_file_name); --- 1168,1176 ----