~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/backend/storage/ipc/pmsignal.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * pmsignal.c
 
4
 *        routines for signaling the postmaster from its child processes
 
5
 *
 
6
 *
 
7
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 
8
 * Portions Copyright (c) 1994, Regents of the University of California
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.18 2004-12-31 22:00:56 pgsql Exp $
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
#include "postgres.h"
 
16
 
 
17
#include <signal.h>
 
18
#include <unistd.h>
 
19
 
 
20
#include "miscadmin.h"
 
21
#include "postmaster/postmaster.h"
 
22
#include "storage/pmsignal.h"
 
23
#include "storage/shmem.h"
 
24
 
 
25
 
 
26
/*
 
27
 * The postmaster is signaled by its children by sending SIGUSR1.  The
 
28
 * specific reason is communicated via flags in shared memory.  We keep
 
29
 * a boolean flag for each possible "reason", so that different reasons
 
30
 * can be signaled by different backends at the same time.      (However,
 
31
 * if the same reason is signaled more than once simultaneously, the
 
32
 * postmaster will observe it only once.)
 
33
 *
 
34
 * The flags are actually declared as "volatile sig_atomic_t" for maximum
 
35
 * portability.  This should ensure that loads and stores of the flag
 
36
 * values are atomic, allowing us to dispense with any explicit locking.
 
37
 */
 
38
 
 
39
static volatile sig_atomic_t *PMSignalFlags;
 
40
 
 
41
 
 
42
/*
 
43
 * PMSignalInit - initialize during shared-memory creation
 
44
 */
 
45
void
 
46
PMSignalInit(void)
 
47
{
 
48
        bool            found;
 
49
 
 
50
        PMSignalFlags = (sig_atomic_t *)
 
51
                ShmemInitStruct("PMSignalFlags", NUM_PMSIGNALS * sizeof(sig_atomic_t), &found);
 
52
 
 
53
        if (!found)
 
54
                MemSet(PMSignalFlags, 0, NUM_PMSIGNALS * sizeof(sig_atomic_t));
 
55
}
 
56
 
 
57
/*
 
58
 * SendPostmasterSignal - signal the postmaster from a child process
 
59
 */
 
60
void
 
61
SendPostmasterSignal(PMSignalReason reason)
 
62
{
 
63
        /* If called in a standalone backend, do nothing */
 
64
        if (!IsUnderPostmaster)
 
65
                return;
 
66
        /* Atomically set the proper flag */
 
67
        PMSignalFlags[reason] = true;
 
68
        /* Send signal to postmaster */
 
69
        kill(PostmasterPid, SIGUSR1);
 
70
}
 
71
 
 
72
/*
 
73
 * CheckPostmasterSignal - check to see if a particular reason has been
 
74
 * signaled, and clear the signal flag.  Should be called by postmaster
 
75
 * after receiving SIGUSR1.
 
76
 */
 
77
bool
 
78
CheckPostmasterSignal(PMSignalReason reason)
 
79
{
 
80
        /* Careful here --- don't clear flag if we haven't seen it set */
 
81
        if (PMSignalFlags[reason])
 
82
        {
 
83
                PMSignalFlags[reason] = false;
 
84
                return true;
 
85
        }
 
86
        return false;
 
87
}
 
88
 
 
89
/*
 
90
 * PostmasterIsAlive - check whether postmaster process is still alive
 
91
 *
 
92
 * amDirectChild should be passed as "true" by code that knows it is
 
93
 * executing in a direct child process of the postmaster; pass "false"
 
94
 * if an indirect child or not sure.  The "true" case uses a faster and
 
95
 * more reliable test, so use it when possible.
 
96
 */
 
97
bool
 
98
PostmasterIsAlive(bool amDirectChild)
 
99
{
 
100
#ifndef WIN32
 
101
        if (amDirectChild)
 
102
        {
 
103
                /*
 
104
                 * If the postmaster is alive, we'll still be its child.  If it's
 
105
                 * died, we'll be reassigned as a child of the init process.
 
106
                 */
 
107
                return (getppid() == PostmasterPid);
 
108
        }
 
109
        else
 
110
        {
 
111
                /*
 
112
                 * Use kill() to see if the postmaster is still alive.  This can
 
113
                 * sometimes give a false positive result, since the postmaster's
 
114
                 * PID may get recycled, but it is good enough for existing uses
 
115
                 * by indirect children.
 
116
                 */
 
117
                return (kill(PostmasterPid, 0) == 0);
 
118
        }
 
119
#else                                                   /* WIN32 */
 
120
        return (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT);
 
121
#endif   /* WIN32 */
 
122
}