30
30
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
31
31
* Portions Copyright (c) 1994, Regents of the University of California
32
32
*
33
- * $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.210 2010/07/06 21:14:25 rhaas Exp $
33
+ * $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.211 2010/07/08 10:20:12 mha Exp $
34
34
*
35
35
*-------------------------------------------------------------------------
36
36
*/
83
83
#ifdef HAVE_UTIME_H
84
84
#include <utime.h>
85
85
#endif
86
+ #ifdef WIN32
87
+ #include <mstcpip.h>
88
+ #endif
86
89
87
90
#include "libpq/ip.h"
88
91
#include "libpq/libpq.h"
@@ -1314,10 +1317,55 @@ pq_endcopyout(bool errorAbort)
1314
1317
* Support for TCP Keepalive parameters
1315
1318
*/
1316
1319
1320
+ /*
1321
+ * On Windows, we need to set both idle and interval at the same time.
1322
+ * We also cannot reset them to the default (setting to zero will
1323
+ * actually set them to zero, not default), therefor we fallback to
1324
+ * the out-of-the-box default instead.
1325
+ */
1326
+ #ifdef WIN32
1327
+ static int
1328
+ pq_setkeepaliveswin32 (Port * port , int idle , int interval )
1329
+ {
1330
+ struct tcp_keepalive ka ;
1331
+ DWORD retsize ;
1332
+
1333
+ if (idle <= 0 )
1334
+ idle = 2 * 60 * 60 ; /* default = 2 hours */
1335
+ if (interval <= 0 )
1336
+ interval = 1 ; /* default = 1 second */
1337
+
1338
+ ka .onoff = 1 ;
1339
+ ka .keepalivetime = idle * 1000 ;
1340
+ ka .keepaliveinterval = interval * 1000 ;
1341
+
1342
+ if (WSAIoctl (port -> sock ,
1343
+ SIO_KEEPALIVE_VALS ,
1344
+ (LPVOID ) & ka ,
1345
+ sizeof (ka ),
1346
+ NULL ,
1347
+ 0 ,
1348
+ & retsize ,
1349
+ NULL ,
1350
+ NULL )
1351
+ != 0 )
1352
+ {
1353
+ elog (LOG , "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui" ,
1354
+ WSAGetLastError ());
1355
+ return STATUS_ERROR ;
1356
+ }
1357
+ if (port -> keepalives_idle != idle )
1358
+ port -> keepalives_idle = idle ;
1359
+ if (port -> keepalives_interval != interval )
1360
+ port -> keepalives_interval = interval ;
1361
+ return STATUS_OK ;
1362
+ }
1363
+ #endif
1364
+
1317
1365
int
1318
1366
pq_getkeepalivesidle (Port * port )
1319
1367
{
1320
- #if defined(TCP_KEEPIDLE ) || defined(TCP_KEEPALIVE )
1368
+ #if defined(TCP_KEEPIDLE ) || defined(TCP_KEEPALIVE ) || defined( WIN32 )
1321
1369
if (port == NULL || IS_AF_UNIX (port -> laddr .addr .ss_family ))
1322
1370
return 0 ;
1323
1371
@@ -1326,6 +1374,7 @@ pq_getkeepalivesidle(Port *port)
1326
1374
1327
1375
if (port -> default_keepalives_idle == 0 )
1328
1376
{
1377
+ #ifndef WIN32
1329
1378
ACCEPT_TYPE_ARG3 size = sizeof (port -> default_keepalives_idle );
1330
1379
1331
1380
#ifdef TCP_KEEPIDLE
@@ -1344,7 +1393,11 @@ pq_getkeepalivesidle(Port *port)
1344
1393
elog (LOG , "getsockopt(TCP_KEEPALIVE) failed: %m" );
1345
1394
port -> default_keepalives_idle = -1 ; /* don't know */
1346
1395
}
1347
- #endif
1396
+ #endif /* TCP_KEEPIDLE */
1397
+ #else /* WIN32 */
1398
+ /* We can't get the defaults on Windows, so return "don't know" */
1399
+ port -> default_keepalives_idle = -1 ;
1400
+ #endif /* WIN32 */
1348
1401
}
1349
1402
1350
1403
return port -> default_keepalives_idle ;
@@ -1359,10 +1412,11 @@ pq_setkeepalivesidle(int idle, Port *port)
1359
1412
if (port == NULL || IS_AF_UNIX (port -> laddr .addr .ss_family ))
1360
1413
return STATUS_OK ;
1361
1414
1362
- #if defined(TCP_KEEPIDLE ) || defined(TCP_KEEPALIVE )
1415
+ #if defined(TCP_KEEPIDLE ) || defined(TCP_KEEPALIVE ) || defined( WIN32 )
1363
1416
if (idle == port -> keepalives_idle )
1364
1417
return STATUS_OK ;
1365
1418
1419
+ #ifndef WIN32
1366
1420
if (port -> default_keepalives_idle <= 0 )
1367
1421
{
1368
1422
if (pq_getkeepalivesidle (port ) < 0 )
@@ -1394,21 +1448,23 @@ pq_setkeepalivesidle(int idle, Port *port)
1394
1448
#endif
1395
1449
1396
1450
port -> keepalives_idle = idle ;
1397
- #else
1451
+ #else /* WIN32 */
1452
+ return pq_setkeepaliveswin32 (port , idle , port -> keepalives_interval );
1453
+ #endif
1454
+ #else /* TCP_KEEPIDLE || WIN32 */
1398
1455
if (idle != 0 )
1399
1456
{
1400
1457
elog (LOG , "setting the keepalive idle time is not supported" );
1401
1458
return STATUS_ERROR ;
1402
1459
}
1403
1460
#endif
1404
-
1405
1461
return STATUS_OK ;
1406
1462
}
1407
1463
1408
1464
int
1409
1465
pq_getkeepalivesinterval (Port * port )
1410
1466
{
1411
- #ifdef TCP_KEEPINTVL
1467
+ #if defined( TCP_KEEPINTVL ) || defined( WIN32 )
1412
1468
if (port == NULL || IS_AF_UNIX (port -> laddr .addr .ss_family ))
1413
1469
return 0 ;
1414
1470
@@ -1417,6 +1473,7 @@ pq_getkeepalivesinterval(Port *port)
1417
1473
1418
1474
if (port -> default_keepalives_interval == 0 )
1419
1475
{
1476
+ #ifndef WIN32
1420
1477
ACCEPT_TYPE_ARG3 size = sizeof (port -> default_keepalives_interval );
1421
1478
1422
1479
if (getsockopt (port -> sock , IPPROTO_TCP , TCP_KEEPINTVL ,
@@ -1426,6 +1483,10 @@ pq_getkeepalivesinterval(Port *port)
1426
1483
elog (LOG , "getsockopt(TCP_KEEPINTVL) failed: %m" );
1427
1484
port -> default_keepalives_interval = -1 ; /* don't know */
1428
1485
}
1486
+ #else
1487
+ /* We can't get the defaults on Windows, so return "don't know" */
1488
+ port -> default_keepalives_interval = -1 ;
1489
+ #endif /* WIN32 */
1429
1490
}
1430
1491
1431
1492
return port -> default_keepalives_interval ;
@@ -1440,10 +1501,11 @@ pq_setkeepalivesinterval(int interval, Port *port)
1440
1501
if (port == NULL || IS_AF_UNIX (port -> laddr .addr .ss_family ))
1441
1502
return STATUS_OK ;
1442
1503
1443
- #ifdef TCP_KEEPINTVL
1504
+ #if defined( TCP_KEEPINTVL ) || defined ( WIN32 )
1444
1505
if (interval == port -> keepalives_interval )
1445
1506
return STATUS_OK ;
1446
1507
1508
+ #ifndef WIN32
1447
1509
if (port -> default_keepalives_interval <= 0 )
1448
1510
{
1449
1511
if (pq_getkeepalivesinterval (port ) < 0 )
@@ -1466,6 +1528,9 @@ pq_setkeepalivesinterval(int interval, Port *port)
1466
1528
}
1467
1529
1468
1530
port -> keepalives_interval = interval ;
1531
+ #else /* WIN32 */
1532
+ return pq_setkeepaliveswin32 (port , port -> keepalives_idle , interval );
1533
+ #endif
1469
1534
#else
1470
1535
if (interval != 0 )
1471
1536
{
0 commit comments