Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit25777f6

Browse files
committed
Fix Windows setitimer() emulation to not depend on delivering an APC
to the main thread. This allows removal of WaitForSingleObjectEx() callsfrom the main thread, thereby allowing us to re-enable Qingqing Zhou'sCHECK_FOR_INTERRUPTS performance improvement. Qingqing, Magnus, et al.
1 parentb835472 commit25777f6

File tree

5 files changed

+87
-50
lines changed

5 files changed

+87
-50
lines changed

‎src/backend/port/win32/signal.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.13 2005/10/21 21:43:45 tgl Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.14 2005/10/25 15:15:16 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -89,16 +89,6 @@ pgwin32_signal_initialize(void)
8989
(errmsg_internal("failed to set console control handler")));
9090
}
9191

92-
/*
93-
* Support routine for CHECK_FOR_INTERRUPTS() macro
94-
*/
95-
void
96-
pgwin32_check_queued_signals(void)
97-
{
98-
if (WaitForSingleObjectEx(pgwin32_signal_event,0, TRUE)==WAIT_OBJECT_0)
99-
pgwin32_dispatch_queued_signals();
100-
}
101-
10292
/*
10393
* Dispatch all signals currently queued and not blocked
10494
* Blocked signals are ignored, and will be fired at the time of

‎src/backend/port/win32/socket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.9 2005/10/15 02:49:23 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.10 2005/10/25 15:15:16 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -93,7 +93,7 @@ TranslateSocketError(void)
9393
staticint
9494
pgwin32_poll_signals(void)
9595
{
96-
if (WaitForSingleObjectEx(pgwin32_signal_event,0, TRUE)==WAIT_OBJECT_0)
96+
if (UNBLOCKED_SIGNAL_QUEUE())
9797
{
9898
pgwin32_dispatch_queued_signals();
9999
errno=EINTR;

‎src/backend/port/win32/timer.c

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
* timer.c
44
* Microsoft Windows Win32 Timer Implementation
55
*
6+
* Limitations of this implementation:
7+
*
8+
* - Does not support interval timer (value->it_interval)
9+
* - Only supports ITIMER_REAL
10+
*
611
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
712
*
813
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/timer.c,v 1.5 2004/12/31 22:00:37 pgsql Exp $
14+
* $PostgreSQL: pgsql/src/backend/port/win32/timer.c,v 1.6 2005/10/25 15:15:16 tgl Exp $
1015
*
1116
*-------------------------------------------------------------------------
1217
*/
@@ -16,56 +21,98 @@
1621
#include"libpq/pqsignal.h"
1722

1823

19-
staticHANDLEtimerHandle=INVALID_HANDLE_VALUE;
24+
/* Communication area for inter-thread communication */
25+
typedefstructtimerCA {
26+
structitimervalvalue;
27+
HANDLEevent;
28+
CRITICAL_SECTIONcrit_sec;
29+
}timerCA;
30+
31+
statictimerCAtimerCommArea;
32+
staticHANDLEtimerThreadHandle=INVALID_HANDLE_VALUE;
2033

21-
staticVOIDCALLBACK
22-
timer_completion(LPVOIDarg,DWORDtimeLow,DWORDtimeHigh)
34+
35+
/* Timer management thread */
36+
staticDWORDWINAPI
37+
pg_timer_thread(LPVOIDparam)
2338
{
24-
pg_queue_signal(SIGALRM);
25-
}
39+
DWORDwaittime;
40+
41+
Assert(param==NULL);
2642

43+
waittime=INFINITE;
44+
45+
for (;;)
46+
{
47+
intr;
48+
49+
r=WaitForSingleObjectEx(timerCommArea.event,waittime, FALSE);
50+
if (r==WAIT_OBJECT_0)
51+
{
52+
/* Event signalled from main thread, change the timer */
53+
EnterCriticalSection(&timerCommArea.crit_sec);
54+
if (timerCommArea.value.it_value.tv_sec==0&&
55+
timerCommArea.value.it_value.tv_usec==0)
56+
waittime=INFINITE;/* Cancel the interrupt */
57+
else
58+
waittime=timerCommArea.value.it_value.tv_usec /10+timerCommArea.value.it_value.tv_sec*1000;
59+
ResetEvent(timerCommArea.event);
60+
LeaveCriticalSection(&timerCommArea.crit_sec);
61+
}
62+
elseif (r==WAIT_TIMEOUT)
63+
{
64+
/* Timeout expired, signal SIGALRM and turn it off */
65+
pg_queue_signal(SIGALRM);
66+
waittime=INFINITE;
67+
}
68+
else
69+
{
70+
/* Should never happen */
71+
Assert(false);
72+
}
73+
}
74+
75+
return0;
76+
}
2777

2878
/*
29-
* Limitations of this implementation:
30-
*
31-
* - Does not support setting ovalue
32-
* - Does not support interval timer (value->it_interval)
33-
* - Only supports ITIMER_REAL
79+
* Win32 setitimer emulation by creating a persistent thread
80+
* to handle the timer setting and notification upon timeout.
3481
*/
3582
int
3683
setitimer(intwhich,conststructitimerval*value,structitimerval*ovalue)
3784
{
38-
LARGE_INTEGERdueTime;
39-
40-
Assert(ovalue==NULL);
4185
Assert(value!=NULL);
4286
Assert(value->it_interval.tv_sec==0&&value->it_interval.tv_usec==0);
4387
Assert(which==ITIMER_REAL);
4488

45-
if (timerHandle==INVALID_HANDLE_VALUE)
89+
if (timerThreadHandle==INVALID_HANDLE_VALUE)
4690
{
47-
/* First call in this backend, createnewtimerobject */
48-
timerHandle=CreateWaitableTimer(NULL, TRUE,NULL);
49-
if (timerHandle==NULL)
91+
/* First call in this backend, createevent and thetimerthread */
92+
timerCommArea.event=CreateEvent(NULL, TRUE, FALSE,NULL);
93+
if (timerCommArea.event==NULL)
5094
ereport(FATAL,
51-
(errmsg_internal("failed to createwaitabletimer: %i", (int)GetLastError())));
52-
}
95+
(errmsg_internal("failed to create timer event: %d",
96+
(int)GetLastError())));
5397

54-
if (value->it_value.tv_sec==0&&
55-
value->it_value.tv_usec==0)
56-
{
57-
/* Turn timer off */
58-
CancelWaitableTimer(timerHandle);
59-
return0;
60-
}
98+
MemSet(&timerCommArea.value,0,sizeof(structitimerval));
99+
100+
InitializeCriticalSection(&timerCommArea.crit_sec);
61101

62-
/* Negative time to SetWaitableTimer means relative time */
63-
dueTime.QuadPart=-(value->it_value.tv_usec*10+value->it_value.tv_sec*10000000L);
102+
timerThreadHandle=CreateThread(NULL,0,pg_timer_thread,NULL,0,NULL);
103+
if (timerThreadHandle==INVALID_HANDLE_VALUE)
104+
ereport(FATAL,
105+
(errmsg_internal("failed to create timer thread: %d",
106+
(int)GetLastError())));
107+
}
64108

65-
/* Turn timer on, or change timer */
66-
if (!SetWaitableTimer(timerHandle,&dueTime,0,timer_completion,NULL, FALSE))
67-
ereport(FATAL,
68-
(errmsg_internal("failed to set waitable timer: %i", (int)GetLastError())));
109+
/* Request the timer thread to change settings */
110+
EnterCriticalSection(&timerCommArea.crit_sec);
111+
if (ovalue)
112+
*ovalue=timerCommArea.value;
113+
timerCommArea.value=*value;
114+
LeaveCriticalSection(&timerCommArea.crit_sec);
115+
SetEvent(timerCommArea.event);
69116

70117
return0;
71118
}

‎src/include/miscadmin.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.182 2005/10/22 17:09:48 tgl Exp $
16+
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.183 2005/10/25 15:15:16 tgl Exp $
1717
*
1818
* NOTES
1919
* some of the information in this file should be moved to other files.
@@ -88,7 +88,8 @@ do { \
8888

8989
#defineCHECK_FOR_INTERRUPTS() \
9090
do { \
91-
pgwin32_check_queued_signals(); \
91+
if (UNBLOCKED_SIGNAL_QUEUE()) \
92+
pgwin32_dispatch_queued_signals(); \
9293
if (InterruptPending) \
9394
ProcessInterrupts(); \
9495
} while(0)

‎src/include/port/win32.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.48 2005/10/21 21:43:46 tgl Exp $ */
1+
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.49 2005/10/25 15:15:16 tgl Exp $ */
22

33
/* undefine and redefine after #include */
44
#undef mkdir
@@ -224,7 +224,6 @@ extern HANDLE pgwin32_initial_signal_pipe;
224224

225225
voidpgwin32_signal_initialize(void);
226226
HANDLEpgwin32_create_signal_listener(pid_tpid);
227-
voidpgwin32_check_queued_signals(void);
228227
voidpgwin32_dispatch_queued_signals(void);
229228
voidpg_queue_signal(intsignum);
230229

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp