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

Commit47df6e7

Browse files
committed
Fix infinite sleep and failes of send in Win32.
1) pgwin32_waitforsinglesocket(): WaitForMultipleObjectsEx now called withfinite timeout (100ms) in case of FP_WRITE and UDP socket. If timeout occursthen pgwin32_waitforsinglesocket() tries to write empty packet goes toWaitForMultipleObjectsEx again.2) pgwin32_send(): add loop around WSASend and pgwin32_waitforsinglesocket().The reason is: for overlapped socket, 'ok' result frompgwin32_waitforsinglesocket() isn't guarantee that socket is still free,it can become busy again and following WSASend call will fail withWSAEWOULDBLOCK error.Seehttp://archives.postgresql.org/pgsql-hackers/2006-10/msg00561.php
1 parentefa0e86 commit47df6e7

File tree

1 file changed

+81
-25
lines changed

1 file changed

+81
-25
lines changed

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

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.13 2006/10/04 00:29:56 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.14 2006/10/13 13:59:47 teodor Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -102,11 +102,23 @@ pgwin32_poll_signals(void)
102102
return0;
103103
}
104104

105+
staticint
106+
isDataGram(SOCKETs) {
107+
inttype;
108+
inttypelen=sizeof(type);
109+
110+
if (getsockopt(s,SOL_SOCKET,SO_TYPE, (char*)&type,&typelen) )
111+
return1;
112+
113+
return (type==SOCK_DGRAM ) ?1 :0;
114+
}
115+
105116
int
106117
pgwin32_waitforsinglesocket(SOCKETs,intwhat)
107118
{
108119
staticHANDLEwaitevent=INVALID_HANDLE_VALUE;
109120
staticSOCKETcurrent_socket=-1;
121+
staticintisUDP=0;
110122
HANDLEevents[2];
111123
intr;
112124

@@ -127,8 +139,12 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
127139
* socket from a previous call
128140
*/
129141

130-
if (current_socket!=s&&current_socket!=-1)
131-
WSAEventSelect(current_socket,waitevent,0);
142+
if (current_socket!=s)
143+
{
144+
if (current_socket!=-1 )
145+
WSAEventSelect(current_socket,waitevent,0);
146+
isUDP=isDataGram(s);
147+
}
132148

133149
current_socket=s;
134150

@@ -140,7 +156,46 @@ pgwin32_waitforsinglesocket(SOCKET s, int what)
140156

141157
events[0]=pgwin32_signal_event;
142158
events[1]=waitevent;
143-
r=WaitForMultipleObjectsEx(2,events, FALSE,INFINITE, TRUE);
159+
160+
/*
161+
* Just a workaround of unknown locking problem with writing
162+
* in UDP socket under high load:
163+
* Client's pgsql backend sleeps infinitely in
164+
* WaitForMultipleObjectsEx, pgstat process sleeps in
165+
* pgwin32_select(). So, we will wait with small
166+
* timeout(0.1 sec) and if sockect is still blocked,
167+
* try WSASend (see comments in pgwin32_select) and wait again.
168+
*/
169+
if ((what&FD_WRITE)&&isUDP)
170+
{
171+
for(;;)
172+
{
173+
r=WaitForMultipleObjectsEx(2,events, FALSE,100, TRUE);
174+
175+
if (r==WAIT_TIMEOUT )
176+
{
177+
charc;
178+
WSABUFbuf;
179+
DWORDsent;
180+
181+
buf.buf=&c;
182+
buf.len=0;
183+
184+
r=WSASend(s,&buf,1,&sent,0,NULL,NULL);
185+
if (r==0)/* Completed - means things are fine! */
186+
return1;
187+
elseif (WSAGetLastError()!=WSAEWOULDBLOCK )
188+
{
189+
TranslateSocketError();
190+
return0;
191+
}
192+
}
193+
else
194+
break;
195+
}
196+
}
197+
else
198+
r=WaitForMultipleObjectsEx(2,events, FALSE,INFINITE, TRUE);
144199

145200
if (r==WAIT_OBJECT_0||r==WAIT_IO_COMPLETION)
146201
{
@@ -280,30 +335,31 @@ pgwin32_send(SOCKET s, char *buf, int len, int flags)
280335
wbuf.len=len;
281336
wbuf.buf=buf;
282337

283-
r=WSASend(s,&wbuf,1,&b,flags,NULL,NULL);
284-
if (r!=SOCKET_ERROR&&b>0)
285-
/* Write succeeded right away */
286-
returnb;
287-
288-
if (r==SOCKET_ERROR&&
289-
WSAGetLastError()!=WSAEWOULDBLOCK)
290-
{
291-
TranslateSocketError();
292-
return-1;
293-
}
294-
295-
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
338+
/*
339+
* Readiness of socket to send data to UDP socket
340+
* may be not true: socket can become busy again! So loop
341+
* until send or error occurs.
342+
*/
343+
for(;;) {
344+
r=WSASend(s,&wbuf,1,&b,flags,NULL,NULL);
345+
if (r!=SOCKET_ERROR&&b>0)
346+
/* Write succeeded right away */
347+
returnb;
348+
349+
if (r==SOCKET_ERROR&&
350+
WSAGetLastError()!=WSAEWOULDBLOCK)
351+
{
352+
TranslateSocketError();
353+
return-1;
354+
}
296355

297-
if (pgwin32_waitforsinglesocket(s,FD_WRITE |FD_CLOSE)==0)
298-
return-1;
356+
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
299357

300-
r=WSASend(s,&wbuf,1,&b,flags,NULL,NULL);
301-
if (r==SOCKET_ERROR)
302-
{
303-
TranslateSocketError();
304-
return-1;
358+
if (pgwin32_waitforsinglesocket(s,FD_WRITE |FD_CLOSE)==0)
359+
return-1;
305360
}
306-
returnb;
361+
362+
return-1;
307363
}
308364

309365

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp