Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+35-60
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

+1-4
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

+1-3
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

+1
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)