/* Note that array elements 0 are unused since they correspond to signal 0 */ staticstruct sigaction pg_signal_array[PG_SIGNAL_COUNT]; static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
/* Initialization */ void
pgwin32_signal_initialize(void)
{ int i;
HANDLE signal_thread_handle;
InitializeCriticalSection(&pg_signal_crit_sec);
for (i = 0; i < PG_SIGNAL_COUNT; i++)
{
pg_signal_array[i].sa_handler = SIG_DFL;
pg_signal_array[i].sa_mask = 0;
pg_signal_array[i].sa_flags = 0;
pg_signal_defaults[i] = SIG_IGN;
}
pg_signal_mask = 0;
pg_signal_queue = 0;
/* Create the global event handle used to flag signals */
pgwin32_signal_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (pgwin32_signal_event == NULL)
ereport(FATAL,
(errmsg_internal("could not create signal event: error code %lu", GetLastError())));
/* Create thread for handling signals */
signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, NULL); if (signal_thread_handle == NULL)
ereport(FATAL,
(errmsg_internal("could not create signal handler thread")));
/* Create console control handle to pick up Ctrl-C etc */ if (!SetConsoleCtrlHandler(pg_console_handler, TRUE))
ereport(FATAL,
(errmsg_internal("could not set console control handler")));
}
/* *Dispatchallsignalscurrentlyqueuedandnotblocked *Blockedsignalsareignored,andwillbefiredatthetimeof *thepqsigprocmask()call.
*/ void
pgwin32_dispatch_queued_signals(void)
{ int exec_mask;
Assert(pgwin32_signal_event != NULL);
EnterCriticalSection(&pg_signal_crit_sec); while ((exec_mask = UNBLOCKED_SIGNAL_QUEUE()) != 0)
{ /* One or more unblocked signals queued for execution */ int i;
for (i = 1; i < PG_SIGNAL_COUNT; i++)
{ if (exec_mask & sigmask(i))
{ /* Execute this signal */ struct sigaction *act = &pg_signal_array[i];
pqsigfunc sig = act->sa_handler;
if (sig == SIG_DFL)
sig = pg_signal_defaults[i];
pg_signal_queue &= ~sigmask(i); if (sig != SIG_ERR && sig != SIG_IGN && sig != SIG_DFL)
{
sigset_t block_mask;
sigset_t save_mask;
EnterCriticalSection(&pg_signal_crit_sec); break; /* Restart outer loop, in case signal mask or *queuehasbeenmodifiedinsidesignal
* handler */
}
}
}
}
ResetEvent(pgwin32_signal_event);
LeaveCriticalSection(&pg_signal_crit_sec);
}
/* signal masking. Only called on main thread, no sync required */ int
pqsigprocmask(int how, const sigset_t *set, sigset_t *oset)
{ if (oset)
*oset = pg_signal_mask;
if (!set) return0;
switch (how)
{ case SIG_BLOCK:
pg_signal_mask |= *set; break; case SIG_UNBLOCK:
pg_signal_mask &= ~*set; break; case SIG_SETMASK:
pg_signal_mask = *set; break; default:
errno = EINVAL; return -1;
}
if (pipe == INVALID_HANDLE_VALUE)
ereport(ERROR,
(errmsg("could not create signal listener pipe for PID %d: error code %lu",
(int) pid, GetLastError())));
/* *Queueasignalforthemainthread,bysettingtheflagbitandevent.
*/ void
pg_queue_signal(int signum)
{
Assert(pgwin32_signal_event != NULL); if (signum >= PG_SIGNAL_COUNT || signum <= 0) return; /* ignore any bad signal number */
/* Set up pipe name, in case we have to re-create the pipe. */
snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%lu", GetCurrentProcessId());
for (;;)
{
BOOL fConnected;
/* Create a new pipe instance if we don't have one. */ if (pipe == INVALID_HANDLE_VALUE)
{
pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
write_stderr("could not create signal listener pipe: error code %lu; retrying\n", GetLastError());
SleepEx(500, FALSE); continue;
}
}
/* *Writesomethingbacktotheclient,allowingits *CallNamedPipe()calltoterminate.
*/
WriteFile(pipe, &sigNum, 1, &bytes, NULL); /* Don't care if it
* works or not */
/* Disconnect from client so that we can re-use the pipe. */
DisconnectNamedPipe(pipe);
} else
{ /* *Connectionfailed.Cleanupandtryagain. * *Thisshouldneverhappen.Ifitdoes,there'sawindowwhere *we'llmisssignalsuntilwemanagetore-createthepipe. *However,justtryingtousethesamepipeagainisprobablynot *goingtowork,sowehavelittlechoice.
*/
CloseHandle(pipe);
pipe = INVALID_HANDLE_VALUE;
}
} return0;
}
/* Console control handler will execute on a thread created
by the OS at the time of invocation */ static BOOL WINAPI
pg_console_handler(DWORD dwCtrlType)
{ if (dwCtrlType == CTRL_C_EVENT ||
dwCtrlType == CTRL_BREAK_EVENT ||
dwCtrlType == CTRL_CLOSE_EVENT ||
dwCtrlType == CTRL_SHUTDOWN_EVENT)
{
pg_queue_signal(SIGINT); return TRUE;
} return FALSE;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.