Обсуждение: Win32 question: getppid() with no parent?

Поиск
Список
Период
Сортировка

Win32 question: getppid() with no parent?

От
Tom Lane
Дата:
On Unix, it is possible to tell whether your parent process has died
by checking to see if you have become a child of init:

    if (getppid() == 1)
       /* oh dear, I am an orphan */

Is there equivalent functionality available on Windows?

Currently, we have the pgstat child process checking for postmaster
death by watching for read-ready on a pipe.  This does not scale
pleasantly to multiple long-lived postmaster children, though, so
I'm wondering about ways for the children to detect a postmaster crash
without requiring any direct postmaster cooperation.

            regards, tom lane

Re: Win32 question: getppid() with no parent?

От
"Magnus Hagander"
Дата:
>On Unix, it is possible to tell whether your parent process has died
>by checking to see if you have become a child of init:
>
>    if (getppid() == 1)
>       /* oh dear, I am an orphan */
>
>Is there equivalent functionality available on Windows?
>
>Currently, we have the pgstat child process checking for postmaster
>death by watching for read-ready on a pipe.  This does not scale
>pleasantly to multiple long-lived postmaster children, though, so
>I'm wondering about ways for the children to detect a postmaster crash
>without requiring any direct postmaster cooperation.

Not really.
http://www.codeguru.com/Cpp/W-P/win32/article.php/c1437/
Can be done, but that's really ugly.

Question though - we keep a PostmasterPid variable, right? One way to do
it is if we n child startup do OpenProcess() on this pid, to return a
HANDLE (the pid may be reused, but an open handle certainly can't). We
can then do a simple:
if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_OBJECT_0)
   /* oh dear, postmaster is gone */

This exepects that we know whom our parent is at process start, which
gettpid doesn't. But it might be enough?


(If we can't rely on that variable, we could do a win32 specific hack
that passes the HANDLE of the postmaster down to the child on exec, I
guess.)

//Magnus

Re: Win32 question: getppid() with no parent?

От
Tom Lane
Дата:
"Magnus Hagander" <mha@sollentuna.net> writes:
> Question though - we keep a PostmasterPid variable, right?

Yeah we do; we must have it to signal the postmaster from the children.

> (If we can't rely on that variable, we could do a win32 specific hack
> that passes the HANDLE of the postmaster down to the child on exec, I
> guess.)

Is this just like passing a variable value, or is there some more
protection involved?

            regards, tom lane

Re: Win32 question: getppid() with no parent?

От
Bruce Momjian
Дата:
Seems we removed a few getppid() calls in January:

    http://archives.postgresql.org/pgsql-patches/2004-01/msg00123.php

I agree --- I don't like the pipe usage we have now.

---------------------------------------------------------------------------

Magnus Hagander wrote:
> >On Unix, it is possible to tell whether your parent process has died
> >by checking to see if you have become a child of init:
> >
> >    if (getppid() == 1)
> >       /* oh dear, I am an orphan */
> >
> >Is there equivalent functionality available on Windows?
> >
> >Currently, we have the pgstat child process checking for postmaster
> >death by watching for read-ready on a pipe.  This does not scale
> >pleasantly to multiple long-lived postmaster children, though, so
> >I'm wondering about ways for the children to detect a postmaster crash
> >without requiring any direct postmaster cooperation.
>
> Not really.
> http://www.codeguru.com/Cpp/W-P/win32/article.php/c1437/
> Can be done, but that's really ugly.
>
> Question though - we keep a PostmasterPid variable, right? One way to do
> it is if we n child startup do OpenProcess() on this pid, to return a
> HANDLE (the pid may be reused, but an open handle certainly can't). We
> can then do a simple:
> if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_OBJECT_0)
>    /* oh dear, postmaster is gone */
>
> This exepects that we know whom our parent is at process start, which
> gettpid doesn't. But it might be enough?
>
>
> (If we can't rely on that variable, we could do a win32 specific hack
> that passes the HANDLE of the postmaster down to the child on exec, I
> guess.)
>
> //Magnus
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: Win32 question: getppid() with no parent?

От
"Magnus Hagander"
Дата:
>> Question though - we keep a PostmasterPid variable, right?
>
>Yeah we do; we must have it to signal the postmaster from the children.
>
>> (If we can't rely on that variable, we could do a win32 specific hack
>> that passes the HANDLE of the postmaster down to the child on exec, I
>> guess.)
>
>Is this just like passing a variable value, or is there some more
>protection involved?

It is passing a variable. *Before* you parse it, you have to make it
inheritable by doing something along the line of:
DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
GetCurrentProcess(), &targetHandle, 0, TRUE, DUPLICATE_SAME_ACCESS);

(If you just do GetCurrentProcess() it will return a hard-coded
pseudohandle. So if you use that handle in the child process, it will
point to the child process. DuplicateHandle will turn it into a real
handle)

//Magnus

Re: Win32 question: getppid() with no parent?

От
Tom Lane
Дата:
"Magnus Hagander" <mha@sollentuna.net> writes:
>>> (If we can't rely on that variable, we could do a win32 specific hack
>>> that passes the HANDLE of the postmaster down to the child on exec, I
>>> guess.)
>>
>> Is this just like passing a variable value, or is there some more
>> protection involved?

> It is passing a variable. *Before* you parse it, you have to make it
> inheritable by doing something along the line of:
> DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
> GetCurrentProcess(), &targetHandle, 0, TRUE, DUPLICATE_SAME_ACCESS);

But you'd do that only once during postmaster start, right?  It's
probably marginally faster/safer to do that than to fabricate a new
handle in each child based on PostmasterPid.

            regards, tom lane

Re: Win32 question: getppid() with no parent?

От
"Magnus Hagander"
Дата:
>>>> (If we can't rely on that variable, we could do a win32
>specific hack
>>>> that passes the HANDLE of the postmaster down to the child
>on exec, I
>>>> guess.)
>>>
>>> Is this just like passing a variable value, or is there some more
>>> protection involved?
>
>> It is passing a variable. *Before* you parse it, you have to make it
>> inheritable by doing something along the line of:
>> DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
>> GetCurrentProcess(), &targetHandle, 0, TRUE, DUPLICATE_SAME_ACCESS);
>
>But you'd do that only once during postmaster start, right?  It's
>probably marginally faster/safer to do that than to fabricate a new
>handle in each child based on PostmasterPid.

Yup, then you could just write the HANDLE vlaue (basically a 32-bit
integer) to the backend startup file and put it on the commandline to
pgstat.
If you need the pgstat process to keep track of it's chlid (the other
pgstat process), you'd need it once there too. Not sure if that's
needed.

And yes, I think it's marginally safer.

//Magnus

Re: Win32 question: getppid() with no parent?

От
Tom Lane
Дата:
"Magnus Hagander" <mha@sollentuna.net> writes:
>> But you'd do that only once during postmaster start, right?  It's
>> probably marginally faster/safer to do that than to fabricate a new
>> handle in each child based on PostmasterPid.

> Yup, then you could just write the HANDLE vlaue (basically a 32-bit
> integer) to the backend startup file

Great.  Could I get someone to implement this now?  The function that
needs it is PostmasterIsAlive() in src/backend/storage/ipc/pmsignal.c.
You can check whether it works by noting whether the stats processes
shut down when the postmaster goes away ...

> If you need the pgstat process to keep track of it's chlid (the other
> pgstat process), you'd need it once there too.

The pgstat processes (and everything else launched by the postmaster)
now use write/read_backend_variables, so copying the handle there should
be sufficient.

            regards, tom lane