Support setting the keepalive idle time on MacOS X.

MacOS X uses TCP_KEEPALIVE rather than TCP_KEEPIDLE for this purpose.

Thanks to Fujii Masao for the review.
This commit is contained in:
Robert Haas 2010-07-06 21:14:25 +00:00
parent 3f12653b73
commit 5acd417c8f
4 changed files with 49 additions and 15 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.291 2010/07/03 22:52:25 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.292 2010/07/06 21:14:25 rhaas Exp $ -->
<chapter Id="runtime-config"> <chapter Id="runtime-config">
<title>Server Configuration</title> <title>Server Configuration</title>
@ -523,11 +523,12 @@ SET ENABLE_SEQSCAN TO OFF;
</indexterm> </indexterm>
<listitem> <listitem>
<para> <para>
On systems that support the <symbol>TCP_KEEPIDLE</symbol> socket option, specifies the On systems that support the <symbol>TCP_KEEPIDLE</symbol> or
<symbol>TCP_KEEPALIVE</> socket option, specifies the
number of seconds between sending keepalives on an otherwise idle number of seconds between sending keepalives on an otherwise idle
connection. A value of zero uses the system default. If <symbol>TCP_KEEPIDLE</symbol> is connection. A value of zero uses the system default. If neither of
not supported, this parameter must be zero. This parameter is ignored for these socket options is supported, this parameter must be zero. This
connections made via a Unix-domain socket. parameter is ignored for connections made via a Unix-domain socket.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.311 2010/06/29 22:29:14 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.312 2010/07/06 21:14:25 rhaas Exp $ -->
<chapter id="libpq"> <chapter id="libpq">
<title><application>libpq</application> - C Library</title> <title><application>libpq</application> - C Library</title>
@ -298,10 +298,10 @@
<para> <para>
Controls the number of seconds of inactivity after which TCP should Controls the number of seconds of inactivity after which TCP should
send a keepalive message to the server. A value of zero uses the send a keepalive message to the server. A value of zero uses the
system default. This parameter is ignored if the system default. This parameter is ignored if the neither the
<symbol>TCP_KEEPIDLE</> socket option is not supported, for <symbol>TCP_KEEPIDLE</> nor the <symbol>TCP_KEEPALIVE</> socket
connections made via a Unix-domain socket, or if keepalives are options are supported, for connections made via a Unix-domain
disabled. socket, or if keepalives are disabled.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -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.209 2010/03/21 00:17:58 petere Exp $ * $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.210 2010/07/06 21:14:25 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1317,7 +1317,7 @@ pq_endcopyout(bool errorAbort)
int int
pq_getkeepalivesidle(Port *port) pq_getkeepalivesidle(Port *port)
{ {
#ifdef TCP_KEEPIDLE #if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE)
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family)) if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
return 0; return 0;
@ -1328,6 +1328,7 @@ pq_getkeepalivesidle(Port *port)
{ {
ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle); ACCEPT_TYPE_ARG3 size = sizeof(port->default_keepalives_idle);
#ifdef TCP_KEEPIDLE
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE, if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
(char *) &port->default_keepalives_idle, (char *) &port->default_keepalives_idle,
&size) < 0) &size) < 0)
@ -1335,6 +1336,15 @@ pq_getkeepalivesidle(Port *port)
elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m"); elog(LOG, "getsockopt(TCP_KEEPIDLE) failed: %m");
port->default_keepalives_idle = -1; /* don't know */ port->default_keepalives_idle = -1; /* don't know */
} }
#else
if (getsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
(char *) &port->default_keepalives_idle,
&size) < 0)
{
elog(LOG, "getsockopt(TCP_KEEPALIVE) failed: %m");
port->default_keepalives_idle = -1; /* don't know */
}
#endif
} }
return port->default_keepalives_idle; return port->default_keepalives_idle;
@ -1349,7 +1359,7 @@ pq_setkeepalivesidle(int idle, Port *port)
if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family)) if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family))
return STATUS_OK; return STATUS_OK;
#ifdef TCP_KEEPIDLE #if defined(TCP_KEEPIDLE) || defined(TCP_KEEPALIVE)
if (idle == port->keepalives_idle) if (idle == port->keepalives_idle)
return STATUS_OK; return STATUS_OK;
@ -1367,18 +1377,27 @@ pq_setkeepalivesidle(int idle, Port *port)
if (idle == 0) if (idle == 0)
idle = port->default_keepalives_idle; idle = port->default_keepalives_idle;
#ifdef TCP_KEEPIDLE
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE, if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPIDLE,
(char *) &idle, sizeof(idle)) < 0) (char *) &idle, sizeof(idle)) < 0)
{ {
elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m"); elog(LOG, "setsockopt(TCP_KEEPIDLE) failed: %m");
return STATUS_ERROR; return STATUS_ERROR;
} }
#else
if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPALIVE,
(char *) &idle, sizeof(idle)) < 0)
{
elog(LOG, "setsockopt(TCP_KEEPALIVE) failed: %m");
return STATUS_ERROR;
}
#endif
port->keepalives_idle = idle; port->keepalives_idle = idle;
#else #else
if (idle != 0) if (idle != 0)
{ {
elog(LOG, "setsockopt(TCP_KEEPIDLE) not supported"); elog(LOG, "setting the keepalive idle time is not supported");
return STATUS_ERROR; return STATUS_ERROR;
} }
#endif #endif

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.395 2010/07/06 19:19:00 momjian Exp $ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.396 2010/07/06 21:14:25 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1008,6 +1008,20 @@ setKeepalivesIdle(PGconn *conn)
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0; return 0;
} }
#else
#ifdef TCP_KEEPALIVE
/* Darwin uses TCP_KEEPALIVE rather than TCP_KEEPIDLE */
if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPALIVE,
(char *) &idle, sizeof(idle)) < 0)
{
char sebuf[256];
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("setsockopt(TCP_KEEPALIVE) failed: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0;
}
#endif
#endif #endif
return 1; return 1;