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
Hide 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 $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
#include <pwd.h>
#include <pwd.h>
#include <unistd.h>
#include <unistd.h>
#if defined(__alpha) && defined(__osf__)
/* no __alpha__ ? */
#if defined(__alpha) && defined(__osf__)
/* no __alpha__ ? */
#include <sys/sysinfo.h>
#include <sys/sysinfo.h>
#include "machine/hal_sysinfo.h"
#include "machine/hal_sysinfo.h"
#define ASSEMBLER
#define ASSEMBLER
...
@@ -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
...
@@ -67,7 +68,7 @@ main(int argc, char *argv[])
...
@@ -67,7 +68,7 @@ main(int argc, char *argv[])
* without help. Avoid adding more here, if you can.
* without help. Avoid adding more here, if you can.
*/
*/
#if defined(__alpha)
/* no __alpha__ ? */
#if defined(__alpha)
/* no __alpha__ ? */
#ifdef NOFIXADE
#ifdef NOFIXADE
int
buffer
[]
=
{
SSIN_UACPROC
,
UAC_SIGBUS
};
int
buffer
[]
=
{
SSIN_UACPROC
,
UAC_SIGBUS
};
#endif
/* NOFIXADE */
#endif
/* NOFIXADE */
...
@@ -77,7 +78,7 @@ main(int argc, char *argv[])
...
@@ -77,7 +78,7 @@ main(int argc, char *argv[])
#endif
/* __alpha */
#endif
/* __alpha */
#ifdef WIN32
#ifdef WIN32
char
*
env_locale
;
char
*
env_locale
;
#endif
#endif
#if defined(NOFIXADE) || defined(NOPRINTADE)
#if defined(NOFIXADE) || defined(NOPRINTADE)
...
@@ -86,7 +87,7 @@ main(int argc, char *argv[])
...
@@ -86,7 +87,7 @@ main(int argc, char *argv[])
syscall
(
SYS_sysmips
,
MIPS_FIXADE
,
0
,
NULL
,
NULL
,
NULL
);
syscall
(
SYS_sysmips
,
MIPS_FIXADE
,
0
,
NULL
,
NULL
,
NULL
);
#endif
#endif
#if defined(__alpha)
/* no __alpha__ ? */
#if defined(__alpha)
/* no __alpha__ ? */
if
(
setsysinfo
(
SSI_NVPAIRS
,
buffer
,
1
,
(
caddr_t
)
NULL
,
if
(
setsysinfo
(
SSI_NVPAIRS
,
buffer
,
1
,
(
caddr_t
)
NULL
,
(
unsigned
long
)
NULL
)
<
0
)
(
unsigned
long
)
NULL
)
<
0
)
fprintf
(
stderr
,
gettext
(
"%s: setsysinfo failed: %s
\n
"
),
fprintf
(
stderr
,
gettext
(
"%s: setsysinfo failed: %s
\n
"
),
...
@@ -96,15 +97,15 @@ main(int argc, char *argv[])
...
@@ -96,15 +97,15 @@ main(int argc, char *argv[])
#if defined(WIN32)
#if defined(WIN32)
{
{
WSADATA
wsaData
;
WSADATA
wsaData
;
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
"
,
...
@@ -129,15 +130,15 @@ main(int argc, char *argv[])
...
@@ -129,15 +130,15 @@ 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,31 +146,32 @@ main(int argc, char *argv[])
...
@@ -145,31 +146,32 @@ 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
/*
* that by querying the environment explicitly first for LC_COLLATE
* Windows uses codepages rather than the environment, so we work
* and LC_CTYPE. We have to do this because initdb passes those values
* around that by querying the environment explicitly first for
* in the environment. If there is nothing there we fall back on the
* LC_COLLATE and LC_CTYPE. We have to do this because initdb passes
* codepage.
* those values in the environment. If there is nothing there we fall
* 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
setlocale
(
LC_COLLATE
,
""
);
setlocale
(
LC_COLLATE
,
""
);
setlocale
(
LC_CTYPE
,
""
);
setlocale
(
LC_CTYPE
,
""
);
...
@@ -213,7 +215,7 @@ main(int argc, char *argv[])
...
@@ -213,7 +215,7 @@ main(int argc, char *argv[])
gettext
(
"
\"
root
\"
execution of the PostgreSQL server is not permitted.
\n
"
gettext
(
"
\"
root
\"
execution of the PostgreSQL server is not permitted.
\n
"
"The server must be started under an unprivileged user ID to prevent
\n
"
"The server must be started under an unprivileged user ID to prevent
\n
"
"possible system security compromise. See the documentation for
\n
"
"possible system security compromise. See the documentation for
\n
"
"more information on how to properly start the server.
\n
"
"more information on how to properly start the server.
\n
"
));
));
exit
(
1
);
exit
(
1
);
}
}
...
@@ -241,14 +243,14 @@ main(int argc, char *argv[])
...
@@ -241,14 +243,14 @@ 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
]);
if
((
len
>=
10
&&
strcmp
(
argv
[
0
]
+
len
-
10
,
"postmaster"
)
==
0
)
if
((
len
>=
10
&&
strcmp
(
argv
[
0
]
+
len
-
10
,
"postmaster"
)
==
0
)
#ifdef WIN32
#ifdef WIN32
||
(
len
>=
14
&&
strcmp
(
argv
[
0
]
+
len
-
14
,
"postmaster.exe"
)
==
0
)
||
(
len
>=
14
&&
strcmp
(
argv
[
0
]
+
len
-
14
,
"postmaster.exe"
)
==
0
)
#endif
#endif
)
)
{
{
...
@@ -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
)
{
{
...
@@ -275,16 +279,16 @@ main(int argc, char *argv[])
...
@@ -275,16 +279,16 @@ main(int argc, char *argv[])
}
}
/*
/*
* If the first argument is "-statBuf", then invoke pgstat_main.
* If the first argument is "-statBuf", then invoke pgstat_main.
*/
*/
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
);
}
}
/*
/*
* If the first argument is "-statCol", then invoke pgstat_mainChild.
* If the first argument is "-statCol", then invoke pgstat_mainChild.
*/
*/
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-statCol"
)
==
0
)
if
(
argc
>
1
&&
strcmp
(
argv
[
1
],
"-statCol"
)
==
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
...
@@ -270,7 +271,7 @@ static void CleanupProc(int pid, int exitstatus);
...
@@ -270,7 +271,7 @@ static void CleanupProc(int pid, int exitstatus);
static
void
LogChildExit
(
int
lev
,
const
char
*
procname
,
static
void
LogChildExit
(
int
lev
,
const
char
*
procname
,
int
pid
,
int
exitstatus
);
int
pid
,
int
exitstatus
);
static
void
BackendInit
(
Port
*
port
);
static
void
BackendInit
(
Port
*
port
);
static
int
BackendRun
(
Port
*
port
);
static
int
BackendRun
(
Port
*
port
);
static
void
ExitPostmaster
(
int
status
);
static
void
ExitPostmaster
(
int
status
);
static
void
usage
(
const
char
*
);
static
void
usage
(
const
char
*
);
static
int
ServerLoop
(
void
);
static
int
ServerLoop
(
void
);
...
@@ -295,14 +296,14 @@ __attribute__((format(printf, 1, 2)));
...
@@ -295,14 +296,14 @@ __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
);
static
pid_t
win32_waitpid
(
int
*
exitstatus
);
static
pid_t
win32_waitpid
(
int
*
exitstatus
);
static
DWORD
WINAPI
win32_sigchld_waiter
(
LPVOID
param
);
static
DWORD
WINAPI
win32_sigchld_waiter
(
LPVOID
param
);
static
pid_t
*
win32_childPIDArray
;
static
pid_t
*
win32_childPIDArray
;
static
HANDLE
*
win32_childHNDArray
;
static
HANDLE
*
win32_childHNDArray
;
static
unsigned
long
win32_numChildren
=
0
;
static
unsigned
long
win32_numChildren
=
0
;
#endif
#endif
...
@@ -310,16 +311,16 @@ static unsigned long win32_numChildren = 0;
...
@@ -310,16 +311,16 @@ static unsigned long win32_numChildren = 0;
static
pid_t
Backend_forkexec
(
Port
*
port
);
static
pid_t
Backend_forkexec
(
Port
*
port
);
static
unsigned
long
tmpBackendFileNum
=
0
;
static
unsigned
long
tmpBackendFileNum
=
0
;
void
read_backend_variables
(
unsigned
long
id
,
Port
*
port
);
void
read_backend_variables
(
unsigned
long
id
,
Port
*
port
);
static
bool
write_backend_variables
(
Port
*
port
);
static
bool
write_backend_variables
(
Port
*
port
);
static
void
ShmemBackendArrayAdd
(
Backend
*
bn
);
static
void
ShmemBackendArrayAdd
(
Backend
*
bn
);
static
void
ShmemBackendArrayRemove
(
pid_t
pid
);
static
void
ShmemBackendArrayRemove
(
pid_t
pid
);
#endif
#endif
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
#define StartBackgroundWriter()
SSDataBase(BS_XLOG_BGWRITER)
#define StartBackgroundWriter()
SSDataBase(BS_XLOG_BGWRITER)
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
static
void
static
void
...
@@ -462,9 +463,9 @@ PostmasterMain(int argc, char *argv[])
...
@@ -462,9 +463,9 @@ PostmasterMain(int argc, char *argv[])
if
(
find_my_exec
(
argv
[
0
],
my_exec_path
)
<
0
)
if
(
find_my_exec
(
argv
[
0
],
my_exec_path
)
<
0
)
elog
(
FATAL
,
elog
(
FATAL
,
gettext
(
"%s: could not locate my own executable path"
),
gettext
(
"%s: could not locate my own executable path"
),
argv
[
0
]);
argv
[
0
]);
get_pkglib_path
(
my_exec_path
,
pkglib_path
);
get_pkglib_path
(
my_exec_path
,
pkglib_path
);
/*
/*
...
@@ -610,7 +611,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -610,7 +611,7 @@ PostmasterMain(int argc, char *argv[])
default:
default:
fprintf
(
stderr
,
fprintf
(
stderr
,
gettext
(
"Try
\"
%s --help
\"
for more information.
\n
"
),
gettext
(
"Try
\"
%s --help
\"
for more information.
\n
"
),
progname
);
progname
);
ExitPostmaster
(
1
);
ExitPostmaster
(
1
);
}
}
...
@@ -635,7 +636,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -635,7 +636,7 @@ PostmasterMain(int argc, char *argv[])
SetDataDir
(
potential_DataDir
);
SetDataDir
(
potential_DataDir
);
ProcessConfigFile
(
PGC_POSTMASTER
);
ProcessConfigFile
(
PGC_POSTMASTER
);
/* If timezone is not set, determine what the OS uses */
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize
();
pg_timezone_initialize
();
...
@@ -687,15 +688,15 @@ PostmasterMain(int argc, char *argv[])
...
@@ -687,15 +688,15 @@ PostmasterMain(int argc, char *argv[])
char
**
p
;
char
**
p
;
ereport
(
DEBUG3
,
ereport
(
DEBUG3
,
(
errmsg_internal
(
"%s: PostmasterMain: initial environ dump:"
,
(
errmsg_internal
(
"%s: PostmasterMain: initial environ dump:"
,
progname
)));
progname
)));
ereport
(
DEBUG3
,
ereport
(
DEBUG3
,
(
errmsg_internal
(
"-----------------------------------------"
)));
(
errmsg_internal
(
"-----------------------------------------"
)));
for
(
p
=
environ
;
*
p
;
++
p
)
for
(
p
=
environ
;
*
p
;
++
p
)
ereport
(
DEBUG3
,
ereport
(
DEBUG3
,
(
errmsg_internal
(
"
\t
%s"
,
*
p
)));
(
errmsg_internal
(
"
\t
%s"
,
*
p
)));
ereport
(
DEBUG3
,
ereport
(
DEBUG3
,
(
errmsg_internal
(
"-----------------------------------------"
)));
(
errmsg_internal
(
"-----------------------------------------"
)));
}
}
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
...
@@ -704,7 +705,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -704,7 +705,7 @@ PostmasterMain(int argc, char *argv[])
(
errmsg
(
"%s: could not locate postgres executable or non-matching version"
,
(
errmsg
(
"%s: could not locate postgres executable or non-matching version"
,
progname
)));
progname
)));
#endif
#endif
/*
/*
* Initialize SSL library, if specified.
* Initialize SSL library, if specified.
*/
*/
...
@@ -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
,
...
@@ -784,11 +785,11 @@ PostmasterMain(int argc, char *argv[])
...
@@ -784,11 +785,11 @@ PostmasterMain(int argc, char *argv[])
ListenSocket
,
MAXLISTEN
);
ListenSocket
,
MAXLISTEN
);
if
(
status
!=
STATUS_OK
)
if
(
status
!=
STATUS_OK
)
ereport
(
WARNING
,
ereport
(
WARNING
,
(
errmsg
(
"could not create listen socket for
\"
%s
\"
"
,
(
errmsg
(
"could not create listen socket for
\"
%s
\"
"
,
curhost
)));
curhost
)));
*
endptr
=
c
;
*
endptr
=
c
;
if
(
c
!=
'\0'
)
if
(
c
!=
'\0'
)
curhost
=
endptr
+
1
;
curhost
=
endptr
+
1
;
else
else
break
;
break
;
}
}
...
@@ -803,7 +804,7 @@ PostmasterMain(int argc, char *argv[])
...
@@ -803,7 +804,7 @@ PostmasterMain(int argc, char *argv[])
""
,
""
,
htonl
(
PostPortNumber
),
htonl
(
PostPortNumber
),
""
,
""
,
(
DNSServiceRegistrationReply
)
reg_reply
,
(
DNSServiceRegistrationReply
)
reg_reply
,
NULL
);
NULL
);
}
}
#endif
#endif
...
@@ -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.
...
@@ -1349,7 +1350,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
...
@@ -1349,7 +1350,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
* Now fetch parameters out of startup packet and save them into the
* Now fetch parameters out of startup packet and save them into the
* Port structure. All data structures attached to the Port struct
* Port structure. All data structures attached to the Port struct
* must be allocated in TopMemoryContext so that they won't disappear
* must be allocated in TopMemoryContext so that they won't disappear
* when we pass them to PostgresMain (see BackendRun).
We need not
* when we pass them to PostgresMain (see BackendRun).
We need not
* worry about leaking this storage on failure, since we aren't in the
* worry about leaking this storage on failure, since we aren't in the
* postmaster process anymore.
* postmaster process anymore.
*/
*/
...
@@ -1523,10 +1524,12 @@ processCancelRequest(Port *port, void *pkt)
...
@@ -1523,10 +1524,12 @@ 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
backendPID
=
(
int
)
ntohl
(
canc
->
backendPID
);
backendPID
=
(
int
)
ntohl
(
canc
->
backendPID
);
...
@@ -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
...
@@ -2087,7 +2091,7 @@ CleanupProc(int pid,
...
@@ -2087,7 +2091,7 @@ CleanupProc(int pid,
if
(
!
FatalError
)
if
(
!
FatalError
)
{
{
LogChildExit
(
LOG
,
LogChildExit
(
LOG
,
(
pid
==
CheckPointPID
)
?
gettext
(
"checkpoint process"
)
:
(
pid
==
CheckPointPID
)
?
gettext
(
"checkpoint process"
)
:
(
pid
==
BgWriterPID
)
?
gettext
(
"bgwriter process"
)
:
(
pid
==
BgWriterPID
)
?
gettext
(
"bgwriter process"
)
:
gettext
(
"server process"
),
gettext
(
"server process"
),
pid
,
exitstatus
);
pid
,
exitstatus
);
...
@@ -2115,7 +2119,7 @@ CleanupProc(int pid,
...
@@ -2115,7 +2119,7 @@ CleanupProc(int pid,
{
{
ereport
(
DEBUG2
,
ereport
(
DEBUG2
,
(
errmsg_internal
(
"sending %s to process %d"
,
(
errmsg_internal
(
"sending %s to process %d"
,
(
SendStop
?
"SIGSTOP"
:
"SIGQUIT"
),
(
SendStop
?
"SIGSTOP"
:
"SIGQUIT"
),
(
int
)
bp
->
pid
)));
(
int
)
bp
->
pid
)));
kill
(
bp
->
pid
,
(
SendStop
?
SIGSTOP
:
SIGQUIT
));
kill
(
bp
->
pid
,
(
SendStop
?
SIGSTOP
:
SIGQUIT
));
}
}
...
@@ -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
{
{
/*
/*
...
@@ -2398,8 +2400,8 @@ split_opts(char **argv, int *argcp, char *s)
...
@@ -2398,8 +2400,8 @@ split_opts(char **argv, int *argcp, char *s)
/*
/*
* BackendInit/Run -- perform authentication [BackendInit], and if successful,
* BackendInit/Run -- perform authentication [BackendInit], and if successful,
*
set up the backend's argument list [BackendRun] and invoke
*
set up the backend's argument list [BackendRun] and invoke
*
backend main()
*
backend main()
*
*
* returns:
* returns:
* Shouldn't return at all.
* Shouldn't return at all.
...
@@ -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
=
""
;
...
@@ -2469,14 +2471,15 @@ BackendInit(Port *port)
...
@@ -2469,14 +2471,15 @@ BackendInit(Port *port)
remote_port
,
sizeof
(
remote_port
),
remote_port
,
sizeof
(
remote_port
),
(
log_hostname
?
0
:
NI_NUMERICHOST
)
|
NI_NUMERICSERV
))
(
log_hostname
?
0
:
NI_NUMERICHOST
)
|
NI_NUMERICSERV
))
{
{
int
ret
=
getnameinfo_all
(
&
port
->
raddr
.
addr
,
port
->
raddr
.
salen
,
int
ret
=
getnameinfo_all
(
&
port
->
raddr
.
addr
,
port
->
raddr
.
salen
,
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"
,
gai_strerror
(
ret
))));
gai_strerror
(
ret
))));
}
}
snprintf
(
remote_ps_data
,
sizeof
(
remote_ps_data
),
snprintf
(
remote_ps_data
,
sizeof
(
remote_ps_data
),
remote_port
[
0
]
==
'\0'
?
"%s"
:
"%s(%s)"
,
remote_port
[
0
]
==
'\0'
?
"%s"
:
"%s(%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 */
...
@@ -2740,20 +2743,22 @@ SubPostmasterMain(int argc, char* argv[])
...
@@ -2740,20 +2743,22 @@ SubPostmasterMain(int argc, char* argv[])
static
pid_t
static
pid_t
Backend_forkexec
(
Port
*
port
)
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
,
char
buf
[
2
][
MAXPGPATH
];
bufc
=
0
,
i
;
char
buf
[
2
][
MAXPGPATH
];
if
(
!
write_backend_variables
(
port
))
if
(
!
write_backend_variables
(
port
))
return
-
1
;
/* log made by write_backend_variables */
return
-
1
;
/* log made by write_backend_variables */
av
[
ac
++
]
=
"postgres"
;
av
[
ac
++
]
=
"postgres"
;
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
));
...
@@ -2762,23 +2767,23 @@ Backend_forkexec(Port *port)
...
@@ -2762,23 +2767,23 @@ Backend_forkexec(Port *port)
/* FIXME: [fork/exec] ExtraOptions? */
/* FIXME: [fork/exec] ExtraOptions? */
av
[
ac
++
]
=
NULL
;
av
[
ac
++
]
=
NULL
;
Assert
(
ac
<=
lengthof
(
av
));
Assert
(
ac
<=
lengthof
(
av
));
#ifdef WIN32
#ifdef WIN32
pid
=
win32_forkexec
(
postgres_exec_path
,
av
);
/* logs on error */
pid
=
win32_forkexec
(
postgres_exec_path
,
av
);
/* logs on error */
#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
...
@@ -2833,7 +2838,7 @@ sigusr1_handler(SIGNAL_ARGS)
...
@@ -2833,7 +2838,7 @@ sigusr1_handler(SIGNAL_ARGS)
ereport
(
LOG
,
ereport
(
LOG
,
(
errmsg
(
"checkpoints are occurring too frequently (%d seconds apart)"
,
(
errmsg
(
"checkpoints are occurring too frequently (%d seconds apart)"
,
elapsed_secs
),
elapsed_secs
),
errhint
(
"Consider increasing the configuration parameter
\"
checkpoint_segments
\"
."
)));
errhint
(
"Consider increasing the configuration parameter
\"
checkpoint_segments
\"
."
)));
}
}
LastSignalledCheckpoint
=
now
;
LastSignalledCheckpoint
=
now
;
}
}
...
@@ -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
;
...
@@ -3092,7 +3098,7 @@ SSDataBase(int xlop)
...
@@ -3092,7 +3098,7 @@ SSDataBase(int xlop)
SSDataBaseInit
(
xlop
);
SSDataBaseInit
(
xlop
);
#else
#else
if
(
!
write_backend_variables
(
NULL
))
if
(
!
write_backend_variables
(
NULL
))
return
-
1
;
/* log issued by write_backend_variables */
return
-
1
;
/* log issued by write_backend_variables */
#endif
#endif
/* Set up command-line arguments for subprocess */
/* Set up command-line arguments for subprocess */
...
@@ -3128,7 +3134,7 @@ SSDataBase(int xlop)
...
@@ -3128,7 +3134,7 @@ SSDataBase(int xlop)
#ifdef EXEC_BACKEND
#ifdef EXEC_BACKEND
/* EXEC_BACKEND case; fork/exec here */
/* EXEC_BACKEND case; fork/exec here */
#ifdef WIN32
#ifdef WIN32
pid
=
win32_forkexec
(
postgres_exec_path
,
av
);
/* logs on error */
pid
=
win32_forkexec
(
postgres_exec_path
,
av
);
/* logs on error */
#else
#else
if
((
pid
=
fork
())
==
0
&&
(
execv
(
postgres_exec_path
,
av
)
==
-
1
))
if
((
pid
=
fork
())
==
0
&&
(
execv
(
postgres_exec_path
,
av
)
==
-
1
))
{
{
...
@@ -3164,7 +3170,7 @@ SSDataBase(int xlop)
...
@@ -3164,7 +3170,7 @@ SSDataBase(int xlop)
break
;
break
;
case
BS_XLOG_BGWRITER
:
case
BS_XLOG_BGWRITER
:
ereport
(
LOG
,
ereport
(
LOG
,
(
errmsg
(
"could not fork bgwriter process: %m"
)));
(
errmsg
(
"could not fork bgwriter process: %m"
)));
break
;
break
;
case
BS_XLOG_SHUTDOWN
:
case
BS_XLOG_SHUTDOWN
:
ereport
(
LOG
,
ereport
(
LOG
,
...
@@ -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
)
{
{
...
@@ -3288,7 +3294,7 @@ extern slock_t *ShmemIndexLock;
...
@@ -3288,7 +3294,7 @@ extern slock_t *ShmemIndexLock;
extern
void
*
ShmemIndexAlloc
;
extern
void
*
ShmemIndexAlloc
;
typedef
struct
LWLock
LWLock
;
typedef
struct
LWLock
LWLock
;
extern
LWLock
*
LWLockArray
;
extern
LWLock
*
LWLockArray
;
extern
slock_t
*
ProcStructLock
;
extern
slock_t
*
ProcStructLock
;
extern
int
pgStatSock
;
extern
int
pgStatSock
;
#define write_var(var,fp) fwrite((void*)&(var),sizeof(var),1,fp)
#define write_var(var,fp) fwrite((void*)&(var),sizeof(var),1,fp)
...
@@ -3297,7 +3303,7 @@ extern int pgStatSock;
...
@@ -3297,7 +3303,7 @@ extern int pgStatSock;
do { \
do { \
Assert(DataDir); \
Assert(DataDir); \
sprintf((buf), \
sprintf((buf), \
"%s/%s/%s.backend_var.%lu",
\
"%s/%s/%s.backend_var.%lu",
\
DataDir, \
DataDir, \
PG_TEMP_FILES_DIR, \
PG_TEMP_FILES_DIR, \
PG_TEMP_FILE_PREFIX, \
PG_TEMP_FILE_PREFIX, \
...
@@ -3307,24 +3313,26 @@ extern int pgStatSock;
...
@@ -3307,24 +3313,26 @@ extern int pgStatSock;
static
bool
static
bool
write_backend_variables
(
Port
*
port
)
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
);
if
(
!
fp
)
if
(
!
fp
)
{
{
/* 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
);
if
(
!
fp
)
if
(
!
fp
)
{
{
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode_for_file_access
(),
(
errcode_for_file_access
(),
errmsg
(
"could not write to file
\"
%s
\"
: %m"
,
filename
)));
errmsg
(
"could not write to file
\"
%s
\"
: %m"
,
filename
)));
return
false
;
return
false
;
}
}
...
@@ -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
))
...
@@ -3380,54 +3388,55 @@ write_backend_variables(Port *port)
...
@@ -3380,54 +3388,55 @@ write_backend_variables(Port *port)
void
void
read_backend_variables
(
unsigned
long
id
,
Port
*
port
)
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
);
if
(
!
fp
)
if
(
!
fp
)
{
{
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode_for_file_access
(),
(
errcode_for_file_access
(),
errmsg
(
"could not read from backend_variables file
\"
%s
\"
: %m"
,
filename
)));
errmsg
(
"could not read from backend_variables file
\"
%s
\"
: %m"
,
filename
)));
return
;
return
;
}
}
/* 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,51 +3500,52 @@ static void ShmemBackendArrayRemove(pid_t pid)
...
@@ -3484,51 +3500,52 @@ 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
;
char
*
p
;
char
*
p
;
int
i
;
int
i
;
char
cmdLine
[
MAXPGPATH
];
char
cmdLine
[
MAXPGPATH
];
HANDLE
childHandleCopy
;
HANDLE
childHandleCopy
;
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
)
...
@@ -3554,15 +3571,16 @@ pid_t win32_forkexec(const char* path, char *argv[])
...
@@ -3554,15 +3571,16 @@ pid_t win32_forkexec(const char* path, char *argv[])
/*
/*
* Note: The following three functions must not be interrupted (eg. by signals).
* Note: The following three functions must not be interrupted (eg. by signals).
*
As the Postgres Win32 signalling architecture (currently) requires polling,
*
As the Postgres Win32 signalling architecture (currently) requires polling,
*
or APC checking functions which aren't used here, this is not an issue.
*
or APC checking functions which aren't used here, this is not an issue.
*
*
*
We keep two separate arrays, instead of a single array of pid/HANDLE structs,
*
We keep two separate arrays, instead of a single array of pid/HANDLE structs,
*
to avoid having to re-create a handle array for WaitForMultipleObjects on
*
to avoid having to re-create a handle array for WaitForMultipleObjects on
*
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