mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Add emulation of non-blocking sockets to the win32 socket/signal layer,
and use this in pq_getbyte_if_available. It's only a limited implementation which swithes the whole emulation layer no non-blocking mode, but that's enough as long as non-blocking is only used during a short period of time, and only one socket is accessed during this time.
This commit is contained in:
parent
492eaefb90
commit
215cbc90f8
@ -30,7 +30,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.202 2010/01/15 09:19:02 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.203 2010/02/16 19:26:02 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -837,9 +837,13 @@ pq_getbyte_if_available(unsigned char *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Temporarily put the socket into non-blocking mode */
|
/* Temporarily put the socket into non-blocking mode */
|
||||||
|
#ifdef WIN32
|
||||||
|
pgwin32_noblock = 1;
|
||||||
|
#else
|
||||||
if (!pg_set_noblock(MyProcPort->sock))
|
if (!pg_set_noblock(MyProcPort->sock))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errmsg("couldn't put socket to non-blocking mode: %m")));
|
(errmsg("couldn't put socket to non-blocking mode: %m")));
|
||||||
|
#endif
|
||||||
MyProcPort->noblock = true;
|
MyProcPort->noblock = true;
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
@ -851,16 +855,24 @@ pq_getbyte_if_available(unsigned char *c)
|
|||||||
* The rest of the backend code assumes the socket is in blocking
|
* The rest of the backend code assumes the socket is in blocking
|
||||||
* mode, so treat failure as FATAL.
|
* mode, so treat failure as FATAL.
|
||||||
*/
|
*/
|
||||||
|
#ifdef WIN32
|
||||||
|
pgwin32_noblock = 0;
|
||||||
|
#else
|
||||||
if (!pg_set_block(MyProcPort->sock))
|
if (!pg_set_block(MyProcPort->sock))
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errmsg("couldn't put socket to blocking mode: %m")));
|
(errmsg("couldn't put socket to blocking mode: %m")));
|
||||||
|
#endif
|
||||||
MyProcPort->noblock = false;
|
MyProcPort->noblock = false;
|
||||||
PG_RE_THROW();
|
PG_RE_THROW();
|
||||||
}
|
}
|
||||||
PG_END_TRY();
|
PG_END_TRY();
|
||||||
|
#ifdef WIN32
|
||||||
|
pgwin32_noblock = 0;
|
||||||
|
#else
|
||||||
if (!pg_set_block(MyProcPort->sock))
|
if (!pg_set_block(MyProcPort->sock))
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errmsg("couldn't put socket to blocking mode: %m")));
|
(errmsg("couldn't put socket to blocking mode: %m")));
|
||||||
|
#endif
|
||||||
MyProcPort->noblock = false;
|
MyProcPort->noblock = false;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -6,13 +6,26 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.23 2010/01/02 16:57:50 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/port/win32/socket.c,v 1.24 2010/02/16 19:26:02 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicate if pgwin32_recv() should operate in non-blocking mode.
|
||||||
|
*
|
||||||
|
* Since the socket emulation layer always sets the actual socket to
|
||||||
|
* non-blocking mode in order to be able to deliver signals, we must
|
||||||
|
* specify this in a separate flag if we actually need non-blocking
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* This flag changes the behaviour *globally* for all socket operations,
|
||||||
|
* so it should only be set for very short periods of time.
|
||||||
|
*/
|
||||||
|
int pgwin32_noblock = 0;
|
||||||
|
|
||||||
#undef socket
|
#undef socket
|
||||||
#undef accept
|
#undef accept
|
||||||
#undef connect
|
#undef connect
|
||||||
@ -310,6 +323,16 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgwin32_noblock)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No data received, and we are in "emulated non-blocking mode", so return
|
||||||
|
* indicating thta we'd block if we were to continue.
|
||||||
|
*/
|
||||||
|
errno = EWOULDBLOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
|
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
|
||||||
|
|
||||||
for (n = 0; n < 5; n++)
|
for (n = 0; n < 5; n++)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.92 2010/02/13 02:34:14 tgl Exp $ */
|
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.93 2010/02/16 19:26:02 mha Exp $ */
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
#define WIN32_ONLY_COMPILER
|
#define WIN32_ONLY_COMPILER
|
||||||
@ -283,6 +283,8 @@ int pgwin32_send(SOCKET s, char *buf, int len, int flags);
|
|||||||
const char *pgwin32_socket_strerror(int err);
|
const char *pgwin32_socket_strerror(int err);
|
||||||
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
|
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
|
||||||
|
|
||||||
|
extern int pgwin32_noblock;
|
||||||
|
|
||||||
/* in backend/port/win32/security.c */
|
/* in backend/port/win32/security.c */
|
||||||
extern int pgwin32_is_admin(void);
|
extern int pgwin32_is_admin(void);
|
||||||
extern int pgwin32_is_service(void);
|
extern int pgwin32_is_service(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user