Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
70d58115
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
70d58115
编写于
1月 27, 2004
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Pgindent win32 signal code.
上级
50491963
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
214 addition
and
173 deletion
+214
-173
src/backend/libpq/pqsignal.c
src/backend/libpq/pqsignal.c
+214
-173
未找到文件。
src/backend/libpq/pqsignal.c
浏览文件 @
70d58115
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/pqsignal.c,v 1.
29 2004/01/27 00:45:26
momjian Exp $
* $PostgreSQL: pgsql/src/backend/libpq/pqsignal.c,v 1.
30 2004/01/27 00:46:58
momjian Exp $
*
* NOTES
* This shouldn't be in libpq, but the monitor and some other
...
...
@@ -169,141 +169,171 @@ pqsignal(int signo, pqsigfunc func)
/* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
* variable that can be accessed from the signal sending threads! */
static
CRITICAL_SECTION
pg_signal_crit_sec
;
static
int
pg_signal_queue
;
static
int
pg_signal_queue
;
#define PG_SIGNAL_COUNT 32
static
pqsigfunc
pg_signal_array
[
PG_SIGNAL_COUNT
];
static
pqsigfunc
pg_signal_defaults
[
PG_SIGNAL_COUNT
];
static
int
pg_signal_mask
;
static
int
pg_signal_mask
;
HANDLE
pgwin32_main_thread_handle
;
HANDLE
pgwin32_main_thread_handle
;
/* Signal handling thread function */
static
DWORD
WINAPI
pg_signal_thread
(
LPVOID
param
);
/* 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
]
=
SIG_DFL
;
pg_signal_defaults
[
i
]
=
SIG_IGN
;
}
pg_signal_mask
=
0
;
pg_signal_queue
=
0
;
/* Get handle to main thread so we can post calls to it later */
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
GetCurrentThread
(),
GetCurrentProcess
(),
&
pgwin32_main_thread_handle
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
))
{
fprintf
(
stderr
,
gettext
(
"Failed to get main thread handle!
\n
"
));
exit
(
1
);
}
/* Create thread for handling signals */
signal_thread_handle
=
CreateThread
(
NULL
,
0
,
pg_signal_thread
,
NULL
,
0
,
NULL
);
if
(
signal_thread_handle
==
NULL
)
{
fprintf
(
stderr
,
gettext
(
"Failed to create signal handler thread!
\n
"
));
exit
(
1
);
}
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
]
=
SIG_DFL
;
pg_signal_defaults
[
i
]
=
SIG_IGN
;
}
pg_signal_mask
=
0
;
pg_signal_queue
=
0
;
/* Get handle to main thread so we can post calls to it later */
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
GetCurrentThread
(),
GetCurrentProcess
(),
&
pgwin32_main_thread_handle
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
))
{
fprintf
(
stderr
,
gettext
(
"Failed to get main thread handle!
\n
"
));
exit
(
1
);
}
/* Create thread for handling signals */
signal_thread_handle
=
CreateThread
(
NULL
,
0
,
pg_signal_thread
,
NULL
,
0
,
NULL
);
if
(
signal_thread_handle
==
NULL
)
{
fprintf
(
stderr
,
gettext
(
"Failed to create signal handler thread!
\n
"
));
exit
(
1
);
}
}
/* Dispatch all signals currently queued and not blocked
/* Dispatch all signals currently queued and not blocked
* Blocked signals are ignored, and will be fired at the time of
* the sigsetmask() call. */
static
void
dispatch_queued_signals
(
void
)
{
int
i
;
EnterCriticalSection
(
&
pg_signal_crit_sec
);
while
(
pg_signal_queue
&
~
pg_signal_mask
)
{
/* One or more unblocked signals queued for execution */
int
exec_mask
=
pg_signal_queue
&
~
pg_signal_mask
;
for
(
i
=
0
;
i
<
PG_SIGNAL_COUNT
;
i
++
)
{
if
(
exec_mask
&
sigmask
(
i
))
{
/* Execute this signal */
pqsigfunc
sig
=
pg_signal_array
[
i
];
if
(
sig
==
SIG_DFL
)
sig
=
pg_signal_defaults
[
i
];
pg_signal_queue
&=
~
sigmask
(
i
);
if
(
sig
!=
SIG_ERR
&&
sig
!=
SIG_IGN
&&
sig
!=
SIG_DFL
)
{
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
sig
(
i
);
EnterCriticalSection
(
&
pg_signal_crit_sec
);
break
;
/* Restart outer loop, in case signal mask or queue
has been modified inside signal handler */
static
void
dispatch_queued_signals
(
void
)
{
int
i
;
EnterCriticalSection
(
&
pg_signal_crit_sec
);
while
(
pg_signal_queue
&
~
pg_signal_mask
)
{
/* One or more unblocked signals queued for execution */
int
exec_mask
=
pg_signal_queue
&
~
pg_signal_mask
;
for
(
i
=
0
;
i
<
PG_SIGNAL_COUNT
;
i
++
)
{
if
(
exec_mask
&
sigmask
(
i
))
{
/* Execute this signal */
pqsigfunc
sig
=
pg_signal_array
[
i
];
if
(
sig
==
SIG_DFL
)
sig
=
pg_signal_defaults
[
i
];
pg_signal_queue
&=
~
sigmask
(
i
);
if
(
sig
!=
SIG_ERR
&&
sig
!=
SIG_IGN
&&
sig
!=
SIG_DFL
)
{
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
sig
(
i
);
EnterCriticalSection
(
&
pg_signal_crit_sec
);
break
;
/* Restart outer loop, in case signal mask
* or queue has been modified inside
* signal handler */
}
}
}
}
}
}
}
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
}
/* signal masking. Only called on main thread, no sync required */
int
pqsigsetmask
(
int
mask
)
{
int
prevmask
;
prevmask
=
pg_signal_mask
;
pg_signal_mask
=
mask
;
/* Dispatch any signals queued up right away, in case we have
unblocked one or more signals previously queued */
dispatch_queued_signals
();
return
prevmask
;
int
pqsigsetmask
(
int
mask
)
{
int
prevmask
;
prevmask
=
pg_signal_mask
;
pg_signal_mask
=
mask
;
/*
* Dispatch any signals queued up right away, in case we have
* unblocked one or more signals previously queued
*/
dispatch_queued_signals
();
return
prevmask
;
}
/* signal manipulation. Only called on main thread, no sync required */
pqsigfunc
pqsignal
(
int
signum
,
pqsigfunc
handler
)
{
pqsigfunc
prevfunc
;
if
(
signum
>=
PG_SIGNAL_COUNT
||
signum
<
0
)
return
SIG_ERR
;
prevfunc
=
pg_signal_array
[
signum
];
pg_signal_array
[
signum
]
=
handler
;
return
prevfunc
;
pqsigfunc
pqsignal
(
int
signum
,
pqsigfunc
handler
)
{
pqsigfunc
prevfunc
;
if
(
signum
>=
PG_SIGNAL_COUNT
||
signum
<
0
)
return
SIG_ERR
;
prevfunc
=
pg_signal_array
[
signum
];
pg_signal_array
[
signum
]
=
handler
;
return
prevfunc
;
}
/* signal sending */
int
pqkill
(
int
pid
,
int
sig
)
{
char
pipename
[
128
];
BYTE
sigData
=
sig
;
BYTE
sigRet
=
0
;
DWORD
bytes
;
if
(
sig
>=
PG_SIGNAL_COUNT
||
sig
<=
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
pid
<=
0
)
{
/* No support for process groups */
errno
=
EINVAL
;
return
-
1
;
}
wsprintf
(
pipename
,
"
\\\\
.
\\
pipe
\\
pgsignal_%i"
,
pid
);
if
(
!
CallNamedPipe
(
pipename
,
&
sigData
,
1
,
&
sigRet
,
1
,
&
bytes
,
1000
))
{
if
(
GetLastError
()
==
ERROR_FILE_NOT_FOUND
)
errno
=
ESRCH
;
else
if
(
GetLastError
()
==
ERROR_ACCESS_DENIED
)
errno
=
EPERM
;
else
errno
=
EINVAL
;
return
-
1
;
}
if
(
bytes
!=
1
||
sigRet
!=
sig
)
{
errno
=
ESRCH
;
return
-
1
;
}
return
0
;
int
pqkill
(
int
pid
,
int
sig
)
{
char
pipename
[
128
];
BYTE
sigData
=
sig
;
BYTE
sigRet
=
0
;
DWORD
bytes
;
if
(
sig
>=
PG_SIGNAL_COUNT
||
sig
<=
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
pid
<=
0
)
{
/* No support for process groups */
errno
=
EINVAL
;
return
-
1
;
}
wsprintf
(
pipename
,
"
\\\\
.
\\
pipe
\\
pgsignal_%i"
,
pid
);
if
(
!
CallNamedPipe
(
pipename
,
&
sigData
,
1
,
&
sigRet
,
1
,
&
bytes
,
1000
))
{
if
(
GetLastError
()
==
ERROR_FILE_NOT_FOUND
)
errno
=
ESRCH
;
else
if
(
GetLastError
()
==
ERROR_ACCESS_DENIED
)
errno
=
EPERM
;
else
errno
=
EINVAL
;
return
-
1
;
}
if
(
bytes
!=
1
||
sigRet
!=
sig
)
{
errno
=
ESRCH
;
return
-
1
;
}
return
0
;
}
/* APC callback scheduled on main thread when signals are fired */
static
void
CALLBACK
pg_signal_apc
(
ULONG_PTR
param
)
{
dispatch_queued_signals
();
static
void
CALLBACK
pg_signal_apc
(
ULONG_PTR
param
)
{
dispatch_queued_signals
();
}
/*
...
...
@@ -314,78 +344,89 @@ static void CALLBACK pg_signal_apc(ULONG_PTR param) {
*/
static
void
pg_queue_signal
(
int
signum
)
{
if
(
signum
>=
PG_SIGNAL_COUNT
||
signum
<
0
)
return
;
EnterCriticalSection
(
&
pg_signal_crit_sec
);
pg_signal_queue
|=
sigmask
(
signum
);
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
QueueUserAPC
(
pg_signal_apc
,
pgwin32_main_thread_handle
,(
ULONG_PTR
)
NULL
);
static
void
pg_queue_signal
(
int
signum
)
{
if
(
signum
>=
PG_SIGNAL_COUNT
||
signum
<
0
)
return
;
EnterCriticalSection
(
&
pg_signal_crit_sec
);
pg_signal_queue
|=
sigmask
(
signum
);
LeaveCriticalSection
(
&
pg_signal_crit_sec
);
QueueUserAPC
(
pg_signal_apc
,
pgwin32_main_thread_handle
,
(
ULONG_PTR
)
NULL
);
}
/* Signal dispatching thread */
static
DWORD
WINAPI
pg_signal_dispatch_thread
(
LPVOID
param
)
{
HANDLE
pipe
=
(
HANDLE
)
param
;
BYTE
sigNum
;
DWORD
bytes
;
if
(
!
ReadFile
(
pipe
,
&
sigNum
,
1
,
&
bytes
,
NULL
))
{
/* Client died before sending */
CloseHandle
(
pipe
);
return
0
;
}
if
(
bytes
!=
1
)
{
/* Received <bytes> bytes over signal pipe (should be 1) */
CloseHandle
(
pipe
);
return
0
;
}
WriteFile
(
pipe
,
&
sigNum
,
1
,
&
bytes
,
NULL
);
/* Don't care if it works or not.. */
FlushFileBuffers
(
pipe
);
DisconnectNamedPipe
(
pipe
);
CloseHandle
(
pipe
);
pg_queue_signal
(
sigNum
);
return
0
;
static
DWORD
WINAPI
pg_signal_dispatch_thread
(
LPVOID
param
)
{
HANDLE
pipe
=
(
HANDLE
)
param
;
BYTE
sigNum
;
DWORD
bytes
;
if
(
!
ReadFile
(
pipe
,
&
sigNum
,
1
,
&
bytes
,
NULL
))
{
/* Client died before sending */
CloseHandle
(
pipe
);
return
0
;
}
if
(
bytes
!=
1
)
{
/* Received <bytes> bytes over signal pipe (should be 1) */
CloseHandle
(
pipe
);
return
0
;
}
WriteFile
(
pipe
,
&
sigNum
,
1
,
&
bytes
,
NULL
);
/* Don't care if it works
* or not.. */
FlushFileBuffers
(
pipe
);
DisconnectNamedPipe
(
pipe
);
CloseHandle
(
pipe
);
pg_queue_signal
(
sigNum
);
return
0
;
}
/* Signal handling thread */
static
DWORD
WINAPI
pg_signal_thread
(
LPVOID
param
)
{
char
pipename
[
128
];
HANDLE
pipe
=
INVALID_HANDLE_VALUE
;
wsprintf
(
pipename
,
"
\\\\
.
\\
pipe
\\
pgsignal_%i"
,
GetCurrentProcessId
());
for
(;;)
{
BOOL
fConnected
;
HANDLE
hThread
;
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
)
{
fprintf
(
stderr
,
gettext
(
"Failed to create signal listener pipe: %i. Retrying.
\n
"
),(
int
)
GetLastError
());
SleepEx
(
500
,
TRUE
);
continue
;
}
fConnected
=
ConnectNamedPipe
(
pipe
,
NULL
)
?
TRUE
:
(
GetLastError
()
==
ERROR_PIPE_CONNECTED
);
if
(
fConnected
)
{
hThread
=
CreateThread
(
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
pg_signal_dispatch_thread
,
(
LPVOID
)
pipe
,
0
,
NULL
);
if
(
hThread
==
INVALID_HANDLE_VALUE
)
{
fprintf
(
stderr
,
gettext
(
"Failed to create signal dispatch thread: %i
\n
"
),(
int
)
GetLastError
());
}
else
CloseHandle
(
hThread
);
}
else
/* Connection failed. Cleanup and try again */
CloseHandle
(
pipe
);
}
return
0
;
static
DWORD
WINAPI
pg_signal_thread
(
LPVOID
param
)
{
char
pipename
[
128
];
HANDLE
pipe
=
INVALID_HANDLE_VALUE
;
wsprintf
(
pipename
,
"
\\\\
.
\\
pipe
\\
pgsignal_%i"
,
GetCurrentProcessId
());
for
(;;)
{
BOOL
fConnected
;
HANDLE
hThread
;
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
)
{
fprintf
(
stderr
,
gettext
(
"Failed to create signal listener pipe: %i. Retrying.
\n
"
),
(
int
)
GetLastError
());
SleepEx
(
500
,
TRUE
);
continue
;
}
fConnected
=
ConnectNamedPipe
(
pipe
,
NULL
)
?
TRUE
:
(
GetLastError
()
==
ERROR_PIPE_CONNECTED
);
if
(
fConnected
)
{
hThread
=
CreateThread
(
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
pg_signal_dispatch_thread
,
(
LPVOID
)
pipe
,
0
,
NULL
);
if
(
hThread
==
INVALID_HANDLE_VALUE
)
fprintf
(
stderr
,
gettext
(
"Failed to create signal dispatch thread: %i
\n
"
),
(
int
)
GetLastError
());
else
CloseHandle
(
hThread
);
}
else
/* Connection failed. Cleanup and try again */
CloseHandle
(
pipe
);
}
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录