Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
bb44a7c5
Commit
bb44a7c5
authored
May 27, 2004
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pgindent files for Tom.
parent
83526ccf
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
284 additions
and
250 deletions
+284
-250
src/backend/main/main.c
src/backend/main/main.c
+43
-39
src/backend/postmaster/postmaster.c
src/backend/postmaster/postmaster.c
+241
-211
No files found.
src/backend/main/main.c
View file @
bb44a7c5
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.8
2 2004/05/25 01:00:2
0 momjian Exp $
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.8
3 2004/05/27 15:07:4
0 momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -50,6 +50,7 @@ int
...
@@ -50,6 +50,7 @@ int
main
(
int
argc
,
char
*
argv
[])
main
(
int
argc
,
char
*
argv
[])
{
{
int
len
;
int
len
;
#ifndef WIN32
#ifndef WIN32
struct
passwd
*
pw
;
struct
passwd
*
pw
;
#endif
#endif
...
@@ -100,11 +101,11 @@ main(int argc, char *argv[])
...
@@ -100,11 +101,11 @@ main(int argc, char *argv[])
int
err
;
int
err
;
/* Make output streams unbuffered by default */
/* Make output streams unbuffered by default */
setvbuf
(
stdout
,
NULL
,
_IONBF
,
0
);
setvbuf
(
stdout
,
NULL
,
_IONBF
,
0
);
setvbuf
(
stderr
,
NULL
,
_IONBF
,
0
);
setvbuf
(
stderr
,
NULL
,
_IONBF
,
0
);
/* Prepare Winsock */
/* Prepare Winsock */
err
=
WSAStartup
(
MAKEWORD
(
2
,
2
),
&
wsaData
);
err
=
WSAStartup
(
MAKEWORD
(
2
,
2
),
&
wsaData
);
if
(
err
!=
0
)
if
(
err
!=
0
)
{
{
fprintf
(
stderr
,
"%s: WSAStartup failed: %d
\n
"
,
fprintf
(
stderr
,
"%s: WSAStartup failed: %d
\n
"
,
...
@@ -130,14 +131,14 @@ main(int argc, char *argv[])
...
@@ -130,14 +131,14 @@ main(int argc, char *argv[])
/*
/*
* Remember the physical location of the initially given argv[] array
* Remember the physical location of the initially given argv[] array
* for possible use by ps display. On some platforms, the argv[]
* for possible use by ps display. On some platforms, the argv[]
* storage must be overwritten in order to set the process title for
ps.
* storage must be overwritten in order to set the process title for
*
In such cases save_ps_display_args makes and returns a new copy of
*
ps. In such cases save_ps_display_args makes and returns a new copy
* the argv[] array.
*
of
the argv[] array.
*
*
* save_ps_display_args may also move the environment strings to make
* save_ps_display_args may also move the environment strings to make
* extra room. Therefore this should be done as early as possible
during
* extra room. Therefore this should be done as early as possible
*
startup, to avoid entanglements with code that might save a getenv()
*
during startup, to avoid entanglements with code that might save a
* result pointer.
*
getenv()
result pointer.
*/
*/
argv
=
save_ps_display_args
(
argc
,
argv
);
argv
=
save_ps_display_args
(
argc
,
argv
);
...
@@ -145,29 +146,30 @@ main(int argc, char *argv[])
...
@@ -145,29 +146,30 @@ main(int argc, char *argv[])
* Set up locale information from environment. Note that LC_CTYPE and
* Set up locale information from environment. Note that LC_CTYPE and
* LC_COLLATE will be overridden later from pg_control if we are in an
* LC_COLLATE will be overridden later from pg_control if we are in an
* already-initialized database. We set them here so that they will
* already-initialized database. We set them here so that they will
* be available to fill pg_control during initdb. LC_MESSAGES will
get
* be available to fill pg_control during initdb. LC_MESSAGES will
*
set later during GUC option processing, but we set it here to allow
*
get set later during GUC option processing, but we set it here to
* startup error messages to be localized.
*
allow
startup error messages to be localized.
*/
*/
set_pglocale
(
argv
[
0
],
"postgres"
);
set_pglocale
(
argv
[
0
],
"postgres"
);
#ifdef WIN32
#ifdef WIN32
/*
/*
* Windows uses codepages rather than the environment, so we work
around
* Windows uses codepages rather than the environment, so we work
*
that by querying the environment explicitly first for LC_COLLATE
*
around that by querying the environment explicitly first for
*
and LC_CTYPE. We have to do this because initdb passes those valu
es
*
LC_COLLATE and LC_CTYPE. We have to do this because initdb pass
es
*
in the environment. If there is nothing there we fall back on the
*
those values in the environment. If there is nothing there we fall
* codepage.
*
back on the
codepage.
*/
*/
if
((
env_locale
=
getenv
(
"LC_COLLATE"
))
!=
NULL
)
if
((
env_locale
=
getenv
(
"LC_COLLATE"
))
!=
NULL
)
setlocale
(
LC_COLLATE
,
env_locale
);
setlocale
(
LC_COLLATE
,
env_locale
);
else
else
setlocale
(
LC_COLLATE
,
""
);
setlocale
(
LC_COLLATE
,
""
);
if
((
env_locale
=
getenv
(
"LC_CTYPE"
))
!=
NULL
)
if
((
env_locale
=
getenv
(
"LC_CTYPE"
))
!=
NULL
)
setlocale
(
LC_CTYPE
,
env_locale
);
setlocale
(
LC_CTYPE
,
env_locale
);
else
else
setlocale
(
LC_CTYPE
,
""
);
setlocale
(
LC_CTYPE
,
""
);
#else
#else
...
@@ -241,8 +243,8 @@ main(int argc, char *argv[])
...
@@ -241,8 +243,8 @@ main(int argc, char *argv[])
/*
/*
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
* SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
* SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
* depending on the program name (and possibly first argument) we
* depending on the program name (and possibly first argument) we
were
*
were
called with. The lack of consistency here is historical.
* called with. The lack of consistency here is historical.
*/
*/
len
=
strlen
(
argv
[
0
]);
len
=
strlen
(
argv
[
0
]);
...
@@ -264,9 +266,11 @@ main(int argc, char *argv[])
...
@@ -264,9 +266,11 @@ main(int argc, char *argv[])
exit
(
BootstrapMain
(
argc
-
1
,
argv
+
1
));
exit
(
BootstrapMain
(
argc
-
1
,
argv
+
1
));
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
/*
/*
* If the first argument is "-forkexec", then invoke SubPostmasterMain. Note
* If the first argument is "-forkexec", then invoke
* we remove "-forkexec" from the arguments passed on to SubPostmasterMain.
* SubPostmasterMain. Note we remove "-forkexec" from the arguments
* passed on to SubPostmasterMain.
*/
*/
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-forkexec"
)
==
0
)
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-forkexec"
)
==
0
)
{
{
...
@@ -279,7 +283,7 @@ main(int argc, char *argv[])
...
@@ -279,7 +283,7 @@ main(int argc, char *argv[])
*/
*/
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-statBuf"
)
==
0
)
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-statBuf"
)
==
0
)
{
{
pgstat_main
(
argc
,
argv
);
pgstat_main
(
argc
,
argv
);
exit
(
0
);
exit
(
0
);
}
}
...
...
src/backend/postmaster/postmaster.c
View file @
bb44a7c5
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.39
5 2004/05/26 18:35:35
momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.39
6 2004/05/27 15:07:41
momjian Exp $
*
*
* NOTES
* NOTES
*
*
...
@@ -180,6 +180,7 @@ static int ListenSocket[MAXLISTEN];
...
@@ -180,6 +180,7 @@ static int ListenSocket[MAXLISTEN];
/* Used to reduce macros tests */
/* Used to reduce macros tests */
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
const
bool
ExecBackend
=
true
;
const
bool
ExecBackend
=
true
;
#else
#else
const
bool
ExecBackend
=
false
;
const
bool
ExecBackend
=
false
;
#endif
#endif
...
@@ -295,7 +296,7 @@ __attribute__((format(printf, 1, 2)));
...
@@ -295,7 +296,7 @@ __attribute__((format(printf, 1, 2)));
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
#ifdef WIN32
#ifdef WIN32
pid_t
win32_forkexec
(
const
char
*
path
,
char
*
argv
[]);
pid_t
win32_forkexec
(
const
char
*
path
,
char
*
argv
[]);
static
void
win32_AddChild
(
pid_t
pid
,
HANDLE
handle
);
static
void
win32_AddChild
(
pid_t
pid
,
HANDLE
handle
);
static
void
win32_RemoveChild
(
pid_t
pid
);
static
void
win32_RemoveChild
(
pid_t
pid
);
...
@@ -772,7 +773,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -772,7 +773,7 @@ PostmasterMain(int argc, char *argv[])
endptr
++
;
endptr
++
;
c
=
*
endptr
;
c
=
*
endptr
;
*
endptr
=
'\0'
;
*
endptr
=
'\0'
;
if
(
strcmp
(
curhost
,
"*"
)
==
0
)
if
(
strcmp
(
curhost
,
"*"
)
==
0
)
status
=
StreamServerPort
(
AF_UNSPEC
,
NULL
,
status
=
StreamServerPort
(
AF_UNSPEC
,
NULL
,
(
unsigned
short
)
PostPortNumber
,
(
unsigned
short
)
PostPortNumber
,
UnixSocketDir
,
UnixSocketDir
,
...
@@ -788,7 +789,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -788,7 +789,7 @@ PostmasterMain(int argc, char *argv[])
curhost
)));
curhost
)));
*
endptr
=
c
;
*
endptr
=
c
;
if
(
c
!=
'\0'
)
if
(
c
!=
'\0'
)
curhost
=
endptr
+
1
;
curhost
=
endptr
+
1
;
else
else
break
;
break
;
}
}
...
@@ -833,8 +834,9 @@ PostmasterMain(int argc, char *argv[])
...
@@ -833,8 +834,9 @@ PostmasterMain(int argc, char *argv[])
reset_shared
(
PostPortNumber
);
reset_shared
(
PostPortNumber
);
/*
/*
* Estimate number of openable files. This must happen after setting up
* Estimate number of openable files. This must happen after setting
* semaphores, because on some platforms semaphores count as open files.
* up semaphores, because on some platforms semaphores count as open
* files.
*/
*/
set_max_safe_fds
();
set_max_safe_fds
();
...
@@ -844,11 +846,12 @@ PostmasterMain(int argc, char *argv[])
...
@@ -844,11 +846,12 @@ PostmasterMain(int argc, char *argv[])
BackendList
=
DLNewList
();
BackendList
=
DLNewList
();
#ifdef WIN32
#ifdef WIN32
/*
/*
* Initialize the child pid/HANDLE arrays
* Initialize the child pid/HANDLE arrays
*/
*/
win32_childPIDArray
=
(
pid_t
*
)
malloc
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
pid_t
));
win32_childPIDArray
=
(
pid_t
*
)
malloc
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
pid_t
));
win32_childHNDArray
=
(
HANDLE
*
)
malloc
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
HANDLE
));
win32_childHNDArray
=
(
HANDLE
*
)
malloc
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
HANDLE
));
if
(
!
win32_childPIDArray
||
!
win32_childHNDArray
)
if
(
!
win32_childPIDArray
||
!
win32_childHNDArray
)
ereport
(
FATAL
,
ereport
(
FATAL
,
(
errcode
(
ERRCODE_OUT_OF_MEMORY
),
(
errcode
(
ERRCODE_OUT_OF_MEMORY
),
...
@@ -947,7 +950,7 @@ pmdaemonize(int argc, char *argv[])
...
@@ -947,7 +950,7 @@ pmdaemonize(int argc, char *argv[])
{
{
#ifdef WIN32
#ifdef WIN32
/* not supported */
/* not supported */
elog
(
FATAL
,
"SilentMode not supported under WIN32"
);
elog
(
FATAL
,
"SilentMode not supported under WIN32"
);
#else
#else
int
i
;
int
i
;
pid_t
pid
;
pid_t
pid
;
...
@@ -1105,16 +1108,14 @@ ServerLoop(void)
...
@@ -1105,16 +1108,14 @@ ServerLoop(void)
}
}
/*
/*
* If no background writer process is running and we should
* If no background writer process is running and we should
do
*
do background writing, start one. It doesn't matter if
*
background writing, start one. It doesn't matter if this fails,
*
this fails,
we'll just try again later.
* we'll just try again later.
*/
*/
if
(
BgWriterPID
==
0
&&
BgWriterPercent
>
0
&&
if
(
BgWriterPID
==
0
&&
BgWriterPercent
>
0
&&
StartupPID
==
0
&&
Shutdown
==
NoShutdown
&&
StartupPID
==
0
&&
Shutdown
==
NoShutdown
&&
!
FatalError
&&
random_seed
!=
0
)
!
FatalError
&&
random_seed
!=
0
)
{
BgWriterPID
=
StartBackgroundWriter
();
BgWriterPID
=
StartBackgroundWriter
();
}
/*
/*
* Wait for something to happen.
* Wait for something to happen.
...
@@ -1523,8 +1524,10 @@ processCancelRequest(Port *port, void *pkt)
...
@@ -1523,8 +1524,10 @@ processCancelRequest(Port *port, void *pkt)
int
backendPID
;
int
backendPID
;
long
cancelAuthCode
;
long
cancelAuthCode
;
Backend
*
bp
;
Backend
*
bp
;
#ifndef EXEC_BACKEND
#ifndef EXEC_BACKEND
Dlelem
*
curr
;
Dlelem
*
curr
;
#else
#else
int
i
;
int
i
;
#endif
#endif
...
@@ -1555,7 +1558,7 @@ processCancelRequest(Port *port, void *pkt)
...
@@ -1555,7 +1558,7 @@ processCancelRequest(Port *port, void *pkt)
#else
#else
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
{
{
bp
=
(
Backend
*
)
&
ShmemBackendArray
[
i
];
bp
=
(
Backend
*
)
&
ShmemBackendArray
[
i
];
#endif
#endif
if
(
bp
->
pid
==
backendPID
)
if
(
bp
->
pid
==
backendPID
)
{
{
...
@@ -1733,8 +1736,8 @@ SIGHUP_handler(SIGNAL_ARGS)
...
@@ -1733,8 +1736,8 @@ SIGHUP_handler(SIGNAL_ARGS)
load_ident
();
load_ident
();
/*
/*
* Tell the background writer to terminate so that we
* Tell the background writer to terminate so that we
will start a
*
will start a
new one with a possibly changed config
* new one with a possibly changed config
*/
*/
if
(
BgWriterPID
!=
0
)
if
(
BgWriterPID
!=
0
)
kill
(
BgWriterPID
,
SIGTERM
);
kill
(
BgWriterPID
,
SIGTERM
);
...
@@ -1829,8 +1832,8 @@ pmdie(SIGNAL_ARGS)
...
@@ -1829,8 +1832,8 @@ pmdie(SIGNAL_ARGS)
* No children left. Shutdown data base system.
* No children left. Shutdown data base system.
*
*
* Unlike the previous case, it is not an error for the shutdown
* Unlike the previous case, it is not an error for the shutdown
* process to be running already (we could get SIGTERM
followed
* process to be running already (we could get SIGTERM
* shortly later by SIGINT).
*
followed
shortly later by SIGINT).
*/
*/
if
(
StartupPID
>
0
||
FatalError
)
/* let reaper() handle
if
(
StartupPID
>
0
||
FatalError
)
/* let reaper() handle
* this */
* this */
...
@@ -1874,6 +1877,7 @@ reaper(SIGNAL_ARGS)
...
@@ -1874,6 +1877,7 @@ reaper(SIGNAL_ARGS)
#ifdef HAVE_WAITPID
#ifdef HAVE_WAITPID
int
status
;
/* backend exit status */
int
status
;
/* backend exit status */
#else
#else
#ifndef WIN32
#ifndef WIN32
union
wait
status
;
/* backend exit status */
union
wait
status
;
/* backend exit status */
...
@@ -1899,10 +1903,10 @@ reaper(SIGNAL_ARGS)
...
@@ -1899,10 +1903,10 @@ reaper(SIGNAL_ARGS)
while
((
pid
=
win32_waitpid
(
&
exitstatus
))
>
0
)
while
((
pid
=
win32_waitpid
(
&
exitstatus
))
>
0
)
{
{
/*
/*
* We need to do this here, and not in CleanupProc, since this
* We need to do this here, and not in CleanupProc, since this
is
*
is to be called on all children when we are done with them.
*
to be called on all children when we are done with them. Could
*
Could move to LogChildExit, but that seems like asking for
*
move to LogChildExit, but that seems like asking for future
*
future
trouble...
* trouble...
*/
*/
win32_RemoveChild
(
pid
);
win32_RemoveChild
(
pid
);
#endif
#endif
...
@@ -2141,9 +2145,7 @@ CleanupProc(int pid,
...
@@ -2141,9 +2145,7 @@ CleanupProc(int pid,
checkpointed
=
0
;
checkpointed
=
0
;
}
}
else
if
(
pid
==
BgWriterPID
)
else
if
(
pid
==
BgWriterPID
)
{
BgWriterPID
=
0
;
BgWriterPID
=
0
;
}
else
else
{
{
/*
/*
...
@@ -2427,7 +2429,7 @@ BackendInit(Port *port)
...
@@ -2427,7 +2429,7 @@ BackendInit(Port *port)
*/
*/
/* save start time for end of session reporting */
/* save start time for end of session reporting */
gettimeofday
(
&
(
port
->
session_start
),
NULL
);
gettimeofday
(
&
(
port
->
session_start
),
NULL
);
/* set these to empty in case they are needed before we set them up */
/* set these to empty in case they are needed before we set them up */
port
->
remote_host
=
""
;
port
->
remote_host
=
""
;
...
@@ -2473,6 +2475,7 @@ BackendInit(Port *port)
...
@@ -2473,6 +2475,7 @@ BackendInit(Port *port)
remote_host
,
sizeof
(
remote_host
),
remote_host
,
sizeof
(
remote_host
),
remote_port
,
sizeof
(
remote_port
),
remote_port
,
sizeof
(
remote_port
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
NI_NUMERICHOST
|
NI_NUMERICSERV
);
if
(
ret
)
if
(
ret
)
ereport
(
WARNING
,
ereport
(
WARNING
,
(
errmsg
(
"getnameinfo_all() failed: %s"
,
(
errmsg
(
"getnameinfo_all() failed: %s"
,
...
@@ -2558,8 +2561,8 @@ BackendRun(Port *port)
...
@@ -2558,8 +2561,8 @@ BackendRun(Port *port)
int
i
;
int
i
;
/*
/*
* Let's clean up ourselves as the postmaster child, and
* Let's clean up ourselves as the postmaster child, and
close the
*
close the
postmaster's other sockets
* postmaster's other sockets
*/
*/
ClosePostmasterPorts
(
true
);
ClosePostmasterPorts
(
true
);
...
@@ -2571,7 +2574,7 @@ BackendRun(Port *port)
...
@@ -2571,7 +2574,7 @@ BackendRun(Port *port)
* PGOPTIONS, but it is not honored until after authentication.)
* PGOPTIONS, but it is not honored until after authentication.)
*/
*/
if
(
PreAuthDelay
>
0
)
if
(
PreAuthDelay
>
0
)
pg_usleep
(
PreAuthDelay
*
1000000L
);
pg_usleep
(
PreAuthDelay
*
1000000L
);
/* Will exit on failure */
/* Will exit on failure */
BackendInit
(
port
);
BackendInit
(
port
);
...
@@ -2686,12 +2689,12 @@ BackendRun(Port *port)
...
@@ -2686,12 +2689,12 @@ BackendRun(Port *port)
* Shouldn't return at all.
* Shouldn't return at all.
*/
*/
void
void
SubPostmasterMain
(
int
argc
,
char
*
argv
[])
SubPostmasterMain
(
int
argc
,
char
*
argv
[])
{
{
unsigned
long
backendID
;
unsigned
long
backendID
;
Port
port
;
Port
port
;
memset
((
void
*
)
&
port
,
0
,
sizeof
(
Port
));
memset
((
void
*
)
&
port
,
0
,
sizeof
(
Port
));
Assert
(
argc
==
2
);
Assert
(
argc
==
2
);
/* Do this sooner rather than later... */
/* Do this sooner rather than later... */
...
@@ -2707,11 +2710,11 @@ SubPostmasterMain(int argc, char* argv[])
...
@@ -2707,11 +2710,11 @@ SubPostmasterMain(int argc, char* argv[])
/* Parse passed-in context */
/* Parse passed-in context */
argc
=
0
;
argc
=
0
;
backendID
=
(
unsigned
long
)
atol
(
argv
[
argc
++
]);
backendID
=
(
unsigned
long
)
atol
(
argv
[
argc
++
]);
DataDir
=
strdup
(
argv
[
argc
++
]);
DataDir
=
strdup
(
argv
[
argc
++
]);
/* Read in file-based context */
/* Read in file-based context */
read_backend_variables
(
backendID
,
&
port
);
read_backend_variables
(
backendID
,
&
port
);
read_nondefault_variables
();
read_nondefault_variables
();
/* Remaining initialization */
/* Remaining initialization */
...
@@ -2742,7 +2745,9 @@ Backend_forkexec(Port *port)
...
@@ -2742,7 +2745,9 @@ Backend_forkexec(Port *port)
{
{
pid_t
pid
;
pid_t
pid
;
char
*
av
[
5
];
char
*
av
[
5
];
int
ac
=
0
,
bufc
=
0
,
i
;
int
ac
=
0
,
bufc
=
0
,
i
;
char
buf
[
2
][
MAXPGPATH
];
char
buf
[
2
][
MAXPGPATH
];
if
(
!
write_backend_variables
(
port
))
if
(
!
write_backend_variables
(
port
))
...
@@ -2752,8 +2757,8 @@ Backend_forkexec(Port *port)
...
@@ -2752,8 +2757,8 @@ Backend_forkexec(Port *port)
av
[
ac
++
]
=
"-forkexec"
;
av
[
ac
++
]
=
"-forkexec"
;
/* Format up context to pass to exec'd process */
/* Format up context to pass to exec'd process */
snprintf
(
buf
[
bufc
++
],
MAXPGPATH
,
"%lu"
,
tmpBackendFileNum
);
snprintf
(
buf
[
bufc
++
],
MAXPGPATH
,
"%lu"
,
tmpBackendFileNum
);
snprintf
(
buf
[
bufc
++
],
MAXPGPATH
,
"
\"
%s
\"
"
,
DataDir
);
snprintf
(
buf
[
bufc
++
],
MAXPGPATH
,
"
\"
%s
\"
"
,
DataDir
);
/* Add to the arg list */
/* Add to the arg list */
Assert
(
bufc
<=
lengthof
(
buf
));
Assert
(
bufc
<=
lengthof
(
buf
));
...
@@ -2770,15 +2775,15 @@ Backend_forkexec(Port *port)
...
@@ -2770,15 +2775,15 @@ Backend_forkexec(Port *port)
#else
#else
/* Fire off execv in child */
/* Fire off execv in child */
if
((
pid
=
fork
())
==
0
&&
(
execv
(
postgres_exec_path
,
av
)
==
-
1
))
if
((
pid
=
fork
())
==
0
&&
(
execv
(
postgres_exec_path
,
av
)
==
-
1
))
/*
/*
* FIXME: [fork/exec] suggestions for what to do here?
* FIXME: [fork/exec] suggestions for what to do here?
Probably OK
*
Probably OK
to issue error (unlike pgstat case)
* to issue error (unlike pgstat case)
*/
*/
abort
();
abort
();
#endif
#endif
return
pid
;
/* Parent returns pid */
return
pid
;
/* Parent returns pid */
}
}
#endif
#endif
...
@@ -2865,8 +2870,9 @@ sigusr1_handler(SIGNAL_ARGS)
...
@@ -2865,8 +2870,9 @@ sigusr1_handler(SIGNAL_ARGS)
if
(
CheckPostmasterSignal
(
PMSIGNAL_WAKEN_CHILDREN
))
if
(
CheckPostmasterSignal
(
PMSIGNAL_WAKEN_CHILDREN
))
{
{
/*
/*
* Send SIGUSR1 to all children (triggers CatchupInterruptHandler).
* Send SIGUSR1 to all children (triggers
* See storage/ipc/sinval[adt].c for the use of this.
* CatchupInterruptHandler). See storage/ipc/sinval[adt].c for the
* use of this.
*/
*/
if
(
Shutdown
==
NoShutdown
)
if
(
Shutdown
==
NoShutdown
)
SignalChildren
(
SIGUSR1
);
SignalChildren
(
SIGUSR1
);
...
@@ -2999,8 +3005,7 @@ SSDataBaseInit(int xlop)
...
@@ -2999,8 +3005,7 @@ SSDataBaseInit(int xlop)
{
{
const
char
*
statmsg
;
const
char
*
statmsg
;
IsUnderPostmaster
=
true
;
/* we are a postmaster subprocess
IsUnderPostmaster
=
true
;
/* we are a postmaster subprocess now */
* now */
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
/* In EXEC case we will not have inherited these settings */
/* In EXEC case we will not have inherited these settings */
...
@@ -3044,6 +3049,7 @@ SSDataBase(int xlop)
...
@@ -3044,6 +3049,7 @@ SSDataBase(int xlop)
{
{
pid_t
pid
;
pid_t
pid
;
Backend
*
bn
;
Backend
*
bn
;
#ifndef EXEC_BACKEND
#ifndef EXEC_BACKEND
#ifdef LINUX_PROFILE
#ifdef LINUX_PROFILE
struct
itimerval
prof_itimer
;
struct
itimerval
prof_itimer
;
...
@@ -3190,8 +3196,8 @@ SSDataBase(int xlop)
...
@@ -3190,8 +3196,8 @@ SSDataBase(int xlop)
/*
/*
* The startup and shutdown processes are not considered normal
* The startup and shutdown processes are not considered normal
* backends, but the checkpoint and bgwriter processes are.
* backends, but the checkpoint and bgwriter processes are.
They must
*
They must
be added to the list of backends.
* be added to the list of backends.
*/
*/
if
(
xlop
==
BS_XLOG_CHECKPOINT
||
xlop
==
BS_XLOG_BGWRITER
)
if
(
xlop
==
BS_XLOG_CHECKPOINT
||
xlop
==
BS_XLOG_BGWRITER
)
{
{
...
@@ -3309,7 +3315,8 @@ write_backend_variables(Port *port)
...
@@ -3309,7 +3315,8 @@ write_backend_variables(Port *port)
{
{
char
filename
[
MAXPGPATH
];
char
filename
[
MAXPGPATH
];
FILE
*
fp
;
FILE
*
fp
;
get_tmp_backend_file_name
(
filename
,
++
tmpBackendFileNum
);
get_tmp_backend_file_name
(
filename
,
++
tmpBackendFileNum
);
/* Open file */
/* Open file */
fp
=
AllocateFile
(
filename
,
PG_BINARY_W
);
fp
=
AllocateFile
(
filename
,
PG_BINARY_W
);
...
@@ -3317,7 +3324,8 @@ write_backend_variables(Port *port)
...
@@ -3317,7 +3324,8 @@ write_backend_variables(Port *port)
{
{
/* As per OpenTemporaryFile... */
/* As per OpenTemporaryFile... */
char
dirname
[
MAXPGPATH
];
char
dirname
[
MAXPGPATH
];
sprintf
(
dirname
,
"%s/%s"
,
DataDir
,
PG_TEMP_FILES_DIR
);
sprintf
(
dirname
,
"%s/%s"
,
DataDir
,
PG_TEMP_FILES_DIR
);
mkdir
(
dirname
,
S_IRWXU
);
mkdir
(
dirname
,
S_IRWXU
);
fp
=
AllocateFile
(
filename
,
PG_BINARY_W
);
fp
=
AllocateFile
(
filename
,
PG_BINARY_W
);
...
@@ -3333,37 +3341,37 @@ write_backend_variables(Port *port)
...
@@ -3333,37 +3341,37 @@ write_backend_variables(Port *port)
/* Write vars */
/* Write vars */
if
(
port
)
if
(
port
)
{
{
write_var
(
port
->
sock
,
fp
);
write_var
(
port
->
sock
,
fp
);
write_var
(
port
->
proto
,
fp
);
write_var
(
port
->
proto
,
fp
);
write_var
(
port
->
laddr
,
fp
);
write_var
(
port
->
laddr
,
fp
);
write_var
(
port
->
raddr
,
fp
);
write_var
(
port
->
raddr
,
fp
);
write_var
(
port
->
canAcceptConnections
,
fp
);
write_var
(
port
->
canAcceptConnections
,
fp
);
write_var
(
port
->
cryptSalt
,
fp
);
write_var
(
port
->
cryptSalt
,
fp
);
write_var
(
port
->
md5Salt
,
fp
);
write_var
(
port
->
md5Salt
,
fp
);
}
}
write_var
(
MyCancelKey
,
fp
);
write_var
(
MyCancelKey
,
fp
);
write_var
(
RedoRecPtr
,
fp
);
write_var
(
RedoRecPtr
,
fp
);
write_var
(
LogwrtResult
,
fp
);
write_var
(
LogwrtResult
,
fp
);
write_var
(
UsedShmemSegID
,
fp
);
write_var
(
UsedShmemSegID
,
fp
);
write_var
(
UsedShmemSegAddr
,
fp
);
write_var
(
UsedShmemSegAddr
,
fp
);
write_var
(
ShmemLock
,
fp
);
write_var
(
ShmemLock
,
fp
);
write_var
(
ShmemIndexLock
,
fp
);
write_var
(
ShmemIndexLock
,
fp
);
write_var
(
ShmemVariableCache
,
fp
);
write_var
(
ShmemVariableCache
,
fp
);
write_var
(
ShmemIndexAlloc
,
fp
);
write_var
(
ShmemIndexAlloc
,
fp
);
write_var
(
ShmemBackendArray
,
fp
);
write_var
(
ShmemBackendArray
,
fp
);
write_var
(
LWLockArray
,
fp
);
write_var
(
LWLockArray
,
fp
);
write_var
(
ProcStructLock
,
fp
);
write_var
(
ProcStructLock
,
fp
);
write_var
(
pgStatSock
,
fp
);
write_var
(
pgStatSock
,
fp
);
write_var
(
PreAuthDelay
,
fp
);
write_var
(
PreAuthDelay
,
fp
);
write_var
(
debug_flag
,
fp
);
write_var
(
debug_flag
,
fp
);
write_var
(
PostmasterPid
,
fp
);
write_var
(
PostmasterPid
,
fp
);
fwrite
((
void
*
)
my_exec_path
,
MAXPGPATH
,
1
,
fp
);
fwrite
((
void
*
)
my_exec_path
,
MAXPGPATH
,
1
,
fp
);
/* Release file */
/* Release file */
if
(
FreeFile
(
fp
))
if
(
FreeFile
(
fp
))
...
@@ -3382,7 +3390,8 @@ read_backend_variables(unsigned long id, Port *port)
...
@@ -3382,7 +3390,8 @@ read_backend_variables(unsigned long id, Port *port)
{
{
char
filename
[
MAXPGPATH
];
char
filename
[
MAXPGPATH
];
FILE
*
fp
;
FILE
*
fp
;
get_tmp_backend_file_name
(
filename
,
id
);
get_tmp_backend_file_name
(
filename
,
id
);
/* Open file */
/* Open file */
fp
=
AllocateFile
(
filename
,
PG_BINARY_R
);
fp
=
AllocateFile
(
filename
,
PG_BINARY_R
);
...
@@ -3397,37 +3406,37 @@ read_backend_variables(unsigned long id, Port *port)
...
@@ -3397,37 +3406,37 @@ read_backend_variables(unsigned long id, Port *port)
/* Read vars */
/* Read vars */
if
(
port
)
if
(
port
)
{
{
read_var
(
port
->
sock
,
fp
);
read_var
(
port
->
sock
,
fp
);
read_var
(
port
->
proto
,
fp
);
read_var
(
port
->
proto
,
fp
);
read_var
(
port
->
laddr
,
fp
);
read_var
(
port
->
laddr
,
fp
);
read_var
(
port
->
raddr
,
fp
);
read_var
(
port
->
raddr
,
fp
);
read_var
(
port
->
canAcceptConnections
,
fp
);
read_var
(
port
->
canAcceptConnections
,
fp
);
read_var
(
port
->
cryptSalt
,
fp
);
read_var
(
port
->
cryptSalt
,
fp
);
read_var
(
port
->
md5Salt
,
fp
);
read_var
(
port
->
md5Salt
,
fp
);
}
}
read_var
(
MyCancelKey
,
fp
);
read_var
(
MyCancelKey
,
fp
);
read_var
(
RedoRecPtr
,
fp
);
read_var
(
RedoRecPtr
,
fp
);
read_var
(
LogwrtResult
,
fp
);
read_var
(
LogwrtResult
,
fp
);
read_var
(
UsedShmemSegID
,
fp
);
read_var
(
UsedShmemSegID
,
fp
);
read_var
(
UsedShmemSegAddr
,
fp
);
read_var
(
UsedShmemSegAddr
,
fp
);
read_var
(
ShmemLock
,
fp
);
read_var
(
ShmemLock
,
fp
);
read_var
(
ShmemIndexLock
,
fp
);
read_var
(
ShmemIndexLock
,
fp
);
read_var
(
ShmemVariableCache
,
fp
);
read_var
(
ShmemVariableCache
,
fp
);
read_var
(
ShmemIndexAlloc
,
fp
);
read_var
(
ShmemIndexAlloc
,
fp
);
read_var
(
ShmemBackendArray
,
fp
);
read_var
(
ShmemBackendArray
,
fp
);
read_var
(
LWLockArray
,
fp
);
read_var
(
LWLockArray
,
fp
);
read_var
(
ProcStructLock
,
fp
);
read_var
(
ProcStructLock
,
fp
);
read_var
(
pgStatSock
,
fp
);
read_var
(
pgStatSock
,
fp
);
read_var
(
PreAuthDelay
,
fp
);
read_var
(
PreAuthDelay
,
fp
);
read_var
(
debug_flag
,
fp
);
read_var
(
debug_flag
,
fp
);
read_var
(
PostmasterPid
,
fp
);
read_var
(
PostmasterPid
,
fp
);
fread
((
void
*
)
my_exec_path
,
MAXPGPATH
,
1
,
fp
);
fread
((
void
*
)
my_exec_path
,
MAXPGPATH
,
1
,
fp
);
/* Release file */
/* Release file */
FreeFile
(
fp
);
FreeFile
(
fp
);
...
@@ -3438,21 +3447,26 @@ read_backend_variables(unsigned long id, Port *port)
...
@@ -3438,21 +3447,26 @@ read_backend_variables(unsigned long id, Port *port)
}
}
size_t
ShmemBackendArraySize
(
void
)
size_t
ShmemBackendArraySize
(
void
)
{
{
return
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
Backend
));
return
(
NUM_BACKENDARRAY_ELEMS
*
sizeof
(
Backend
));
}
}
void
ShmemBackendArrayAllocation
(
void
)
void
ShmemBackendArrayAllocation
(
void
)
{
{
size_t
size
=
ShmemBackendArraySize
();
size_t
size
=
ShmemBackendArraySize
();
ShmemBackendArray
=
(
Backend
*
)
ShmemAlloc
(
size
);
ShmemBackendArray
=
(
Backend
*
)
ShmemAlloc
(
size
);
memset
(
ShmemBackendArray
,
0
,
size
);
memset
(
ShmemBackendArray
,
0
,
size
);
}
}
static
void
ShmemBackendArrayAdd
(
Backend
*
bn
)
static
void
ShmemBackendArrayAdd
(
Backend
*
bn
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
{
{
/* Find an empty slot */
/* Find an empty slot */
...
@@ -3467,9 +3481,11 @@ static void ShmemBackendArrayAdd(Backend *bn)
...
@@ -3467,9 +3481,11 @@ static void ShmemBackendArrayAdd(Backend *bn)
(
errmsg_internal
(
"unable to add backend entry"
)));
(
errmsg_internal
(
"unable to add backend entry"
)));
}
}
static
void
ShmemBackendArrayRemove
(
pid_t
pid
)
static
void
ShmemBackendArrayRemove
(
pid_t
pid
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
for
(
i
=
0
;
i
<
NUM_BACKENDARRAY_ELEMS
;
i
++
)
{
{
if
(
ShmemBackendArray
[
i
].
pid
==
pid
)
if
(
ShmemBackendArray
[
i
].
pid
==
pid
)
...
@@ -3484,12 +3500,12 @@ static void ShmemBackendArrayRemove(pid_t pid)
...
@@ -3484,12 +3500,12 @@ static void ShmemBackendArrayRemove(pid_t pid)
(
errmsg_internal
(
"unable to find backend entry with pid %d"
,
(
errmsg_internal
(
"unable to find backend entry with pid %d"
,
pid
)));
pid
)));
}
}
#endif
#endif
#ifdef WIN32
#ifdef WIN32
pid_t
win32_forkexec
(
const
char
*
path
,
char
*
argv
[])
pid_t
win32_forkexec
(
const
char
*
path
,
char
*
argv
[])
{
{
STARTUPINFO
si
;
STARTUPINFO
si
;
PROCESS_INFORMATION
pi
;
PROCESS_INFORMATION
pi
;
...
@@ -3500,35 +3516,36 @@ pid_t win32_forkexec(const char* path, char *argv[])
...
@@ -3500,35 +3516,36 @@ pid_t win32_forkexec(const char* path, char *argv[])
HANDLE
waiterThread
;
HANDLE
waiterThread
;
/* Format the cmd line */
/* Format the cmd line */
snprintf
(
cmdLine
,
sizeof
(
cmdLine
),
"
\"
%s
\"
"
,
path
);
snprintf
(
cmdLine
,
sizeof
(
cmdLine
),
"
\"
%s
\"
"
,
path
);
i
=
0
;
i
=
0
;
while
(
argv
[
++
i
]
!=
NULL
)
while
(
argv
[
++
i
]
!=
NULL
)
{
{
/* FIXME: [fork/exec] some strlen checks might be prudent here */
/* FIXME: [fork/exec] some strlen checks might be prudent here */
strcat
(
cmdLine
,
" "
);
strcat
(
cmdLine
,
" "
);
strcat
(
cmdLine
,
argv
[
i
]);
strcat
(
cmdLine
,
argv
[
i
]);
}
}
/*
/*
* The following snippet can disappear when we consistently
* The following snippet can disappear when we consistently
use
*
use
forward slashes.
* forward slashes.
*/
*/
p
=
cmdLine
;
p
=
cmdLine
;
while
(
*
(
p
++
)
!=
'\0'
)
while
(
*
(
p
++
)
!=
'\0'
)
if
(
*
p
==
'/'
)
*
p
=
'\\'
;
if
(
*
p
==
'/'
)
*
p
=
'\\'
;
memset
(
&
pi
,
0
,
sizeof
(
pi
));
memset
(
&
pi
,
0
,
sizeof
(
pi
));
memset
(
&
si
,
0
,
sizeof
(
si
));
memset
(
&
si
,
0
,
sizeof
(
si
));
si
.
cb
=
sizeof
(
si
);
si
.
cb
=
sizeof
(
si
);
if
(
!
CreateProcess
(
NULL
,
cmdLine
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
))
if
(
!
CreateProcess
(
NULL
,
cmdLine
,
NULL
,
NULL
,
TRUE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
))
{
{
elog
(
ERROR
,
"CreateProcess call failed (%i): %m"
,(
int
)
GetLastError
());
elog
(
ERROR
,
"CreateProcess call failed (%i): %m"
,
(
int
)
GetLastError
());
return
-
1
;
return
-
1
;
}
}
if
(
!
IsUnderPostmaster
)
if
(
!
IsUnderPostmaster
)
/* We are the Postmaster creating a child... */
/* We are the Postmaster creating a child... */
win32_AddChild
(
pi
.
dwProcessId
,
pi
.
hProcess
);
win32_AddChild
(
pi
.
dwProcessId
,
pi
.
hProcess
);
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
pi
.
hProcess
,
pi
.
hProcess
,
...
@@ -3538,11 +3555,11 @@ pid_t win32_forkexec(const char* path, char *argv[])
...
@@ -3538,11 +3555,11 @@ pid_t win32_forkexec(const char* path, char *argv[])
FALSE
,
FALSE
,
DUPLICATE_SAME_ACCESS
))
DUPLICATE_SAME_ACCESS
))
ereport
(
FATAL
,
ereport
(
FATAL
,
(
errmsg_internal
(
"failed to duplicate child handle: %i"
,
(
int
)
GetLastError
())));
(
errmsg_internal
(
"failed to duplicate child handle: %i"
,
(
int
)
GetLastError
())));
waiterThread
=
CreateThread
(
NULL
,
64
*
1024
,
win32_sigchld_waiter
,
(
LPVOID
)
childHandleCopy
,
0
,
NULL
);
waiterThread
=
CreateThread
(
NULL
,
64
*
1024
,
win32_sigchld_waiter
,
(
LPVOID
)
childHandleCopy
,
0
,
NULL
);
if
(
!
waiterThread
)
if
(
!
waiterThread
)
ereport
(
FATAL
,
ereport
(
FATAL
,
(
errmsg_internal
(
"failed to create sigchld waiter thread: %i"
,
(
int
)
GetLastError
())));
(
errmsg_internal
(
"failed to create sigchld waiter thread: %i"
,
(
int
)
GetLastError
())));
CloseHandle
(
waiterThread
);
CloseHandle
(
waiterThread
);
if
(
IsUnderPostmaster
)
if
(
IsUnderPostmaster
)
...
@@ -3562,7 +3579,8 @@ pid_t win32_forkexec(const char* path, char *argv[])
...
@@ -3562,7 +3579,8 @@ pid_t win32_forkexec(const char* path, char *argv[])
* each call to win32_waitpid.
* each call to win32_waitpid.
*/
*/
static
void
win32_AddChild
(
pid_t
pid
,
HANDLE
handle
)
static
void
win32_AddChild
(
pid_t
pid
,
HANDLE
handle
)
{
{
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
if
(
win32_numChildren
<
NUM_BACKENDARRAY_ELEMS
)
if
(
win32_numChildren
<
NUM_BACKENDARRAY_ELEMS
)
...
@@ -3577,9 +3595,11 @@ static void win32_AddChild(pid_t pid, HANDLE handle)
...
@@ -3577,9 +3595,11 @@ static void win32_AddChild(pid_t pid, HANDLE handle)
pid
)));
pid
)));
}
}
static
void
win32_RemoveChild
(
pid_t
pid
)
static
void
win32_RemoveChild
(
pid_t
pid
)
{
{
int
i
;
int
i
;
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
for
(
i
=
0
;
i
<
win32_numChildren
;
i
++
)
for
(
i
=
0
;
i
<
win32_numChildren
;
i
++
)
...
@@ -3601,27 +3621,28 @@ static void win32_RemoveChild(pid_t pid)
...
@@ -3601,27 +3621,28 @@ static void win32_RemoveChild(pid_t pid)
pid
)));
pid
)));
}
}
static
pid_t
win32_waitpid
(
int
*
exitstatus
)
static
pid_t
win32_waitpid
(
int
*
exitstatus
)
{
{
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
Assert
(
win32_childPIDArray
&&
win32_childHNDArray
);
elog
(
DEBUG3
,
"waiting on %lu children"
,
win32_numChildren
);
elog
(
DEBUG3
,
"waiting on %lu children"
,
win32_numChildren
);
if
(
win32_numChildren
>
0
)
if
(
win32_numChildren
>
0
)
{
{
/*
/*
* Note: Do NOT use WaitForMultipleObjectsEx, as we don't
* Note: Do NOT use WaitForMultipleObjectsEx, as we don't
want to
*
want to
run queued APCs here.
* run queued APCs here.
*/
*/
int
index
;
int
index
;
DWORD
exitCode
;
DWORD
exitCode
;
DWORD
ret
=
WaitForMultipleObjects
(
win32_numChildren
,
win32_childHNDArray
,
FALSE
,
0
);
DWORD
ret
=
WaitForMultipleObjects
(
win32_numChildren
,
win32_childHNDArray
,
FALSE
,
0
);
switch
(
ret
)
switch
(
ret
)
{
{
case
WAIT_FAILED
:
case
WAIT_FAILED
:
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errmsg_internal
(
"failed to wait on %lu children: %i"
,
(
errmsg_internal
(
"failed to wait on %lu children: %i"
,
win32_numChildren
,(
int
)
GetLastError
())));
win32_numChildren
,
(
int
)
GetLastError
())));
/* Fall through to WAIT_TIMEOUTs return */
/* Fall through to WAIT_TIMEOUTs return */
case
WAIT_TIMEOUT
:
case
WAIT_TIMEOUT
:
...
@@ -3629,18 +3650,24 @@ static pid_t win32_waitpid(int *exitstatus)
...
@@ -3629,18 +3650,24 @@ static pid_t win32_waitpid(int *exitstatus)
return
-
1
;
return
-
1
;
default:
default:
/* Get the exit code, and return the PID of, the respective process */
index
=
ret
-
WAIT_OBJECT_0
;
/*
* Get the exit code, and return the PID of, the
* respective process
*/
index
=
ret
-
WAIT_OBJECT_0
;
Assert
(
index
>=
0
&&
index
<
win32_numChildren
);
Assert
(
index
>=
0
&&
index
<
win32_numChildren
);
if
(
!
GetExitCodeProcess
(
win32_childHNDArray
[
index
],
&
exitCode
))
if
(
!
GetExitCodeProcess
(
win32_childHNDArray
[
index
],
&
exitCode
))
/*
/*
* If we get this far, this should never happen, but, then again...
* If we get this far, this should never happen, but,
* No choice other than to assume a catastrophic failure.
* then again... No choice other than to assume a
* catastrophic failure.
*/
*/
ereport
(
FATAL
,
ereport
(
FATAL
,
(
errmsg_internal
(
"failed to get exit code for child %lu"
,
(
errmsg_internal
(
"failed to get exit code for child %lu"
,
win32_childPIDArray
[
index
])));
win32_childPIDArray
[
index
])));
*
exitstatus
=
(
int
)
exitCode
;
*
exitstatus
=
(
int
)
exitCode
;
return
win32_childPIDArray
[
index
];
return
win32_childPIDArray
[
index
];
}
}
}
}
...
@@ -3651,14 +3678,17 @@ static pid_t win32_waitpid(int *exitstatus)
...
@@ -3651,14 +3678,17 @@ static pid_t win32_waitpid(int *exitstatus)
/* Note! Code belows executes on separate threads, one for
/* Note! Code belows executes on separate threads, one for
each child process created */
each child process created */
static
DWORD
WINAPI
win32_sigchld_waiter
(
LPVOID
param
)
{
static
DWORD
WINAPI
HANDLE
procHandle
=
(
HANDLE
)
param
;
win32_sigchld_waiter
(
LPVOID
param
)
{
HANDLE
procHandle
=
(
HANDLE
)
param
;
DWORD
r
=
WaitForSingleObject
(
procHandle
,
INFINITE
);
DWORD
r
=
WaitForSingleObject
(
procHandle
,
INFINITE
);
if
(
r
==
WAIT_OBJECT_0
)
if
(
r
==
WAIT_OBJECT_0
)
pg_queue_signal
(
SIGCHLD
);
pg_queue_signal
(
SIGCHLD
);
else
else
fprintf
(
stderr
,
"ERROR: Failed to wait on child process handle: %i
\n
"
,(
int
)
GetLastError
());
fprintf
(
stderr
,
"ERROR: Failed to wait on child process handle: %i
\n
"
,
(
int
)
GetLastError
());
CloseHandle
(
procHandle
);
CloseHandle
(
procHandle
);
return
0
;
return
0
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment