Skip to content

Commit 210eb9b

Browse files
committed
Centralize libpq's low-level code for dropping a connection.
Create an internal function pqDropConnection that does the physical socket close and cleans up closely-associated state. This removes a bunch of ad hoc, not always consistent closure code. The ulterior motive is to have a single place to wait for a spawned child backend to exit, but this seems like good cleanup even if that never happens. I went back and forth on whether to include "conn->status = CONNECTION_BAD" in pqDropConnection's actions, but for the moment decided not to. Only a minority of the call sites actually want that, and in any case it's arguable that conn->status is slightly higher-level state, and thus not part of this function's purview.
1 parent dda589c commit 210eb9b

File tree

4 files changed

+38
-67
lines changed

4 files changed

+38
-67
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 35 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,28 @@ static void default_threadlock(int acquire);
344344
pgthreadlock_t pg_g_threadlock = default_threadlock;
345345

346346

347+
/*
348+
* pqDropConnection
349+
*
350+
* Close any physical connection to the server, and reset associated
351+
* state inside the connection object. We don't release state that
352+
* would be needed to reconnect, though.
353+
*/
354+
void
355+
pqDropConnection(PGconn *conn)
356+
{
357+
/* Drop any SSL state */
358+
pqsecure_close(conn);
359+
/* Close the socket itself */
360+
if (conn->sock >= 0)
361+
closesocket(conn->sock);
362+
conn->sock = -1;
363+
/* Discard any unread/unsent data */
364+
conn->inStart = conn->inCursor = conn->inEnd = 0;
365+
conn->outCount = 0;
366+
}
367+
368+
347369
/*
348370
* Connecting to a Database
349371
*
@@ -1416,12 +1438,7 @@ connectDBStart(PGconn *conn)
14161438
return 1;
14171439

14181440
connect_errReturn:
1419-
if (conn->sock >= 0)
1420-
{
1421-
pqsecure_close(conn);
1422-
closesocket(conn->sock);
1423-
conn->sock = -1;
1424-
}
1441+
pqDropConnection(conn);
14251442
conn->status = CONNECTION_BAD;
14261443
return 0;
14271444
}
@@ -1644,8 +1661,7 @@ PQconnectPoll(PGconn *conn)
16441661
{
16451662
if (!connectNoDelay(conn))
16461663
{
1647-
closesocket(conn->sock);
1648-
conn->sock = -1;
1664+
pqDropConnection(conn);
16491665
conn->addr_cur = addr_cur->ai_next;
16501666
continue;
16511667
}
@@ -1655,8 +1671,7 @@ PQconnectPoll(PGconn *conn)
16551671
appendPQExpBuffer(&conn->errorMessage,
16561672
libpq_gettext("could not set socket to non-blocking mode: %s\n"),
16571673
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1658-
closesocket(conn->sock);
1659-
conn->sock = -1;
1674+
pqDropConnection(conn);
16601675
conn->addr_cur = addr_cur->ai_next;
16611676
continue;
16621677
}
@@ -1667,8 +1682,7 @@ PQconnectPoll(PGconn *conn)
16671682
appendPQExpBuffer(&conn->errorMessage,
16681683
libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
16691684
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1670-
closesocket(conn->sock);
1671-
conn->sock = -1;
1685+
pqDropConnection(conn);
16721686
conn->addr_cur = addr_cur->ai_next;
16731687
continue;
16741688
}
@@ -1715,8 +1729,7 @@ PQconnectPoll(PGconn *conn)
17151729

17161730
if (err)
17171731
{
1718-
closesocket(conn->sock);
1719-
conn->sock = -1;
1732+
pqDropConnection(conn);
17201733
conn->addr_cur = addr_cur->ai_next;
17211734
continue;
17221735
}
@@ -1802,11 +1815,7 @@ PQconnectPoll(PGconn *conn)
18021815
* failure and keep going if there are more addresses.
18031816
*/
18041817
connectFailureMessage(conn, SOCK_ERRNO);
1805-
if (conn->sock >= 0)
1806-
{
1807-
closesocket(conn->sock);
1808-
conn->sock = -1;
1809-
}
1818+
pqDropConnection(conn);
18101819

18111820
/*
18121821
* Try the next address, if any.
@@ -1851,18 +1860,14 @@ PQconnectPoll(PGconn *conn)
18511860
* error message.
18521861
*/
18531862
connectFailureMessage(conn, optval);
1863+
pqDropConnection(conn);
18541864

18551865
/*
18561866
* If more addresses remain, keep trying, just as in the
18571867
* case where connect() returned failure immediately.
18581868
*/
18591869
if (conn->addr_cur->ai_next != NULL)
18601870
{
1861-
if (conn->sock >= 0)
1862-
{
1863-
closesocket(conn->sock);
1864-
conn->sock = -1;
1865-
}
18661871
conn->addr_cur = conn->addr_cur->ai_next;
18671872
conn->status = CONNECTION_NEEDED;
18681873
goto keep_going;
@@ -2137,12 +2142,8 @@ PQconnectPoll(PGconn *conn)
21372142
/* only retry once */
21382143
conn->allow_ssl_try = false;
21392144
/* Must drop the old connection */
2140-
closesocket(conn->sock);
2141-
conn->sock = -1;
2145+
pqDropConnection(conn);
21422146
conn->status = CONNECTION_NEEDED;
2143-
/* Discard any unread/unsent data */
2144-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2145-
conn->outCount = 0;
21462147
goto keep_going;
21472148
}
21482149
}
@@ -2252,13 +2253,8 @@ PQconnectPoll(PGconn *conn)
22522253
{
22532254
conn->pversion = PG_PROTOCOL(2, 0);
22542255
/* Must drop the old connection */
2255-
pqsecure_close(conn);
2256-
closesocket(conn->sock);
2257-
conn->sock = -1;
2256+
pqDropConnection(conn);
22582257
conn->status = CONNECTION_NEEDED;
2259-
/* Discard any unread/unsent data */
2260-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2261-
conn->outCount = 0;
22622258
goto keep_going;
22632259
}
22642260

@@ -2323,12 +2319,8 @@ PQconnectPoll(PGconn *conn)
23232319
/* only retry once */
23242320
conn->wait_ssl_try = false;
23252321
/* Must drop the old connection */
2326-
closesocket(conn->sock);
2327-
conn->sock = -1;
2322+
pqDropConnection(conn);
23282323
conn->status = CONNECTION_NEEDED;
2329-
/* Discard any unread/unsent data */
2330-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2331-
conn->outCount = 0;
23322324
goto keep_going;
23332325
}
23342326

@@ -2343,13 +2335,8 @@ PQconnectPoll(PGconn *conn)
23432335
/* only retry once */
23442336
conn->allow_ssl_try = false;
23452337
/* Must drop the old connection */
2346-
pqsecure_close(conn);
2347-
closesocket(conn->sock);
2348-
conn->sock = -1;
2338+
pqDropConnection(conn);
23492339
conn->status = CONNECTION_NEEDED;
2350-
/* Discard any unread/unsent data */
2351-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2352-
conn->outCount = 0;
23532340
goto keep_going;
23542341
}
23552342
#endif
@@ -2509,13 +2496,8 @@ PQconnectPoll(PGconn *conn)
25092496
PQclear(res);
25102497
conn->send_appname = false;
25112498
/* Must drop the old connection */
2512-
pqsecure_close(conn);
2513-
closesocket(conn->sock);
2514-
conn->sock = -1;
2499+
pqDropConnection(conn);
25152500
conn->status = CONNECTION_NEEDED;
2516-
/* Discard any unread/unsent data */
2517-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2518-
conn->outCount = 0;
25192501
goto keep_going;
25202502
}
25212503
}
@@ -2909,12 +2891,7 @@ closePGconn(PGconn *conn)
29092891
/*
29102892
* Close the connection, reset all transient state, flush I/O buffers.
29112893
*/
2912-
if (conn->sock >= 0)
2913-
{
2914-
pqsecure_close(conn);
2915-
closesocket(conn->sock);
2916-
}
2917-
conn->sock = -1;
2894+
pqDropConnection(conn);
29182895
conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
29192896
* absent */
29202897
conn->asyncStatus = PGASYNC_IDLE;
@@ -2943,8 +2920,6 @@ closePGconn(PGconn *conn)
29432920
if (conn->lobjfuncs)
29442921
free(conn->lobjfuncs);
29452922
conn->lobjfuncs = NULL;
2946-
conn->inStart = conn->inCursor = conn->inEnd = 0;
2947-
conn->outCount = 0;
29482923
#ifdef ENABLE_GSS
29492924
{
29502925
OM_uint32 min_s;

src/interfaces/libpq/fe-misc.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -780,11 +780,8 @@ pqReadData(PGconn *conn)
780780
* has been set already.
781781
*/
782782
definitelyFailed:
783+
pqDropConnection(conn);
783784
conn->status = CONNECTION_BAD; /* No more connection to backend */
784-
pqsecure_close(conn);
785-
closesocket(conn->sock);
786-
conn->sock = -1;
787-
788785
return -1;
789786
}
790787

src/interfaces/libpq/fe-protocol3.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,7 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
430430
pqSaveErrorResult(conn);
431431
conn->asyncStatus = PGASYNC_READY; /* drop out of GetResult wait loop */
432432

433-
pqsecure_close(conn);
434-
closesocket(conn->sock);
435-
conn->sock = -1;
433+
pqDropConnection(conn);
436434
conn->status = CONNECTION_BAD; /* No more connection to backend */
437435
}
438436

src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ extern char *const pgresStatus[];
488488

489489
/* === in fe-connect.c === */
490490

491+
extern void pqDropConnection(PGconn *conn);
491492
extern int pqPacketSend(PGconn *conn, char pack_type,
492493
const void *buf, size_t buf_len);
493494
extern bool pqGetHomeDirectory(char *buf, int bufsize);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy