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

Commit815fcd0

Browse files
committed
pg_upgrade: fix -j race condition on Windows
Pg_Upgrade cannot write the command string to the log file and then callsystem() to write to the same file without causing occasional file-shareerrors on Windows. So instead, write the command string to the log fileafter system(), in those cases.Backpatch to 9.3.
1 parent5691de6 commit815fcd0

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

‎contrib/pg_upgrade/exec.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,29 @@ static intwin32_check_directory_write_permissions(void);
3737
* If throw_error is true, this raises a PG_FATAL error and pg_upgrade
3838
* terminates; otherwise it is just reported as PG_REPORT and exec_prog()
3939
* returns false.
40+
*
41+
* The code requires it be called first from the primary thread on Windows.
4042
*/
4143
bool
4244
exec_prog(constchar*log_file,constchar*opt_log_file,
4345
boolthrow_error,constchar*fmt,...)
4446
{
45-
intresult;
47+
intresult=0;
4648
intwritten;
4749

4850
#defineMAXCMDLEN (2 * MAXPGPATH)
4951
charcmd[MAXCMDLEN];
5052
FILE*log;
5153
va_listap;
5254

55+
#ifdefWIN32
56+
staticDWORDmainThreadId=0;
57+
58+
/* We assume we are called from the primary thread first */
59+
if (mainThreadId==0)
60+
mainThreadId=GetCurrentThreadId();
61+
#endif
62+
5363
written=strlcpy(cmd,SYSTEMQUOTE,sizeof(cmd));
5464
va_start(ap,fmt);
5565
written+=vsnprintf(cmd+written,MAXCMDLEN-written,fmt,ap);
@@ -61,6 +71,22 @@ exec_prog(const char *log_file, const char *opt_log_file,
6171
if (written >=MAXCMDLEN)
6272
pg_log(PG_FATAL,"command too long\n");
6373

74+
pg_log(PG_VERBOSE,"%s\n",cmd);
75+
76+
#ifdefWIN32
77+
/*
78+
* For some reason, Windows issues a file-in-use error if we write data
79+
* to the log file from a non-primary thread just before we create a
80+
* subprocess that also writes to the same log file. One fix is to
81+
* sleep for 100ms. A cleaner fix is to write to the log file _after_
82+
* the subprocess has completed, so we do this only when writing from
83+
* a non-primary thread. fflush(), running system() twice, and
84+
* pre-creating the file do not see to help.
85+
*/
86+
if (mainThreadId!=GetCurrentThreadId())
87+
result=system(cmd);
88+
#endif
89+
6490
log=fopen(log_file,"a");
6591

6692
#ifdefWIN32
@@ -84,19 +110,30 @@ exec_prog(const char *log_file, const char *opt_log_file,
84110

85111
if (log==NULL)
86112
pg_log(PG_FATAL,"cannot write to log file %s\n",log_file);
113+
87114
#ifdefWIN32
88-
fprintf(log,"\n\n");
115+
/* Are we printing "command:" before its output? */
116+
if (mainThreadId==GetCurrentThreadId())
117+
fprintf(log,"\n\n");
89118
#endif
90-
pg_log(PG_VERBOSE,"%s\n",cmd);
91119
fprintf(log,"command: %s\n",cmd);
120+
#ifdefWIN32
121+
/* Are we printing "command:" after its output? */
122+
if (mainThreadId!=GetCurrentThreadId())
123+
fprintf(log,"\n\n");
124+
#endif
92125

93126
/*
94127
* In Windows, we must close the log file at this point so the file is not
95128
* open while the command is running, or we get a share violation.
96129
*/
97130
fclose(log);
98131

99-
result=system(cmd);
132+
#ifdefWIN32
133+
/* see comment above */
134+
if (mainThreadId==GetCurrentThreadId())
135+
#endif
136+
result=system(cmd);
100137

101138
if (result!=0)
102139
{
@@ -118,7 +155,6 @@ exec_prog(const char *log_file, const char *opt_log_file,
118155
}
119156

120157
#ifndefWIN32
121-
122158
/*
123159
* We can't do this on Windows because it will keep the "pg_ctl start"
124160
* output filename open until the server stops, so we do the \n\n above on

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp