Skip to content

Commit 10d7287

Browse files
committed
Libpq non-blocking mode, from Alfred Perlstein
1 parent b1e891d commit 10d7287

File tree

6 files changed

+341
-47
lines changed

6 files changed

+341
-47
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ PostgresPollingStatusType *PQconnectPoll(PQconn *conn)
376376
tested under Windows, and so it is currently off by default. This may be
377377
changed in the future.
378378
</para>
379+
<para>
380+
These functions leave the socket in a non-blocking state as if
381+
<function>PQsetnonblocking</function> had been called.
382+
</para>
379383
<para>
380384
These functions are not thread-safe.
381385
</para>
@@ -1168,8 +1172,58 @@ discarded by <function>PQexec</function>.
11681172
Applications that do not like these limitations can instead use the
11691173
underlying functions that <function>PQexec</function> is built from:
11701174
<function>PQsendQuery</function> and <function>PQgetResult</function>.
1175+
</para>
1176+
<para>
1177+
Older programs that used this functionality as well as
1178+
<function>PQputline</function> and <function>PQputnbytes</function>
1179+
could block waiting to send data to the backend, to
1180+
address that issue, the function <function>PQsetnonblocking</function>
1181+
was added.
1182+
</para>
1183+
<para>
1184+
Old applications can neglect to use <function>PQsetnonblocking</function>
1185+
and get the older potentially blocking behavior. Newer programs can use
1186+
<function>PQsetnonblocking</function> to achieve a completely non-blocking
1187+
connection to the backend.
11711188

11721189
<itemizedlist>
1190+
<listitem>
1191+
<para>
1192+
<function>PQsetnonblocking</function> Sets the state of the connection
1193+
to non-blocking.
1194+
<synopsis>
1195+
int PQsetnonblocking(PGconn *conn)
1196+
</synopsis>
1197+
this function will ensure that calls to
1198+
<function>PQputline</function>, <function>PQputnbytes</function>,
1199+
<function>PQsendQuery</function> and <function>PQendcopy</function>
1200+
will not block but instead return an error if they need to be called
1201+
again.
1202+
</para>
1203+
<para>
1204+
When a database connection has been set to non-blocking mode and
1205+
<function>PQexec</function> is called, it will temporarily set the state
1206+
of the connection to blocking until the <function>PQexec</function>
1207+
completes.
1208+
</para>
1209+
<para>
1210+
More of libpq is expected to be made safe for
1211+
<function>PQsetnonblocking</function> functionality in the near future.
1212+
</para>
1213+
</listitem>
1214+
1215+
<listitem>
1216+
<para>
1217+
<function>PQisnonblocking</function>
1218+
Returns the blocking status of the database connection.
1219+
<synopsis>
1220+
int PQisnonblocking(const PGconn *conn)
1221+
</synopsis>
1222+
Returns TRUE if the connection is set to non-blocking mode,
1223+
FALSE if blocking.
1224+
</para>
1225+
</listitem>
1226+
11731227
<listitem>
11741228
<para>
11751229
<function>PQsendQuery</function>
@@ -1265,23 +1319,46 @@ state will never end.
12651319
</para>
12661320
</listitem>
12671321

1322+
<listitem>
1323+
<para>
1324+
<function>PQflush</function> Attempt to flush any data queued to the backend,
1325+
returns 0 if successful (or if the send queue is empty) or EOF if it failed for
1326+
some reason.
1327+
<synopsis>
1328+
int PQflush(PGconn *conn);
1329+
</synopsis>
1330+
<function>PQflush</function> needs to be called on a non-blocking connection
1331+
before calling <function>select</function> to determine if a responce has
1332+
arrived. If 0 is returned it ensures that there is no data queued to the
1333+
backend that has not actually been sent. Only applications that have used
1334+
<function>PQsetnonblocking</function> have a need for this.
1335+
</para>
1336+
</listitem>
1337+
12681338
<listitem>
12691339
<para>
12701340
<function>PQsocket</function>
12711341
Obtain the file descriptor number for the backend connection socket.
1272-
A valid descriptor will be >= 0; a result of -1 indicates that
1342+
A valid descriptor will be &gt;= 0; a result of -1 indicates that
12731343
no backend connection is currently open.
12741344
<synopsis>
12751345
int PQsocket(const PGconn *conn);
12761346
</synopsis>
12771347
<function>PQsocket</function> should be used to obtain the backend socket descriptor
12781348
in preparation for executing <function>select</function>(2). This allows an
1279-
application to wait for either backend responses or other conditions.
1349+
application using a blocking connection to wait for either backend responses or
1350+
other conditions.
12801351
If the result of <function>select</function>(2) indicates that data can be read from
12811352
the backend socket, then <function>PQconsumeInput</function> should be called to read the
12821353
data; after which, <function>PQisBusy</function>, <function>PQgetResult</function>,
12831354
and/or <function>PQnotifies</function> can be used to process the response.
12841355
</para>
1356+
<para>
1357+
Non-blocking connections (that have used <function>PQsetnonblocking</function>)
1358+
should not use <function>select</function> until <function>PQflush</function>
1359+
has returned 0 indicating that there is no buffered data waiting to be sent
1360+
to the backend.
1361+
</para>
12851362
</listitem>
12861363

12871364
</itemizedlist>

src/interfaces/libpq/fe-connect.c

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.111 2000/01/16 21:18:52 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.112 2000/01/18 06:09:24 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -594,31 +594,6 @@ update_db_info(PGconn *conn)
594594
return 0;
595595
}
596596

597-
598-
/* ----------
599-
* connectMakeNonblocking -
600-
* Make a connection non-blocking.
601-
* Returns 1 if successful, 0 if not.
602-
* ----------
603-
*/
604-
static int
605-
connectMakeNonblocking(PGconn *conn)
606-
{
607-
#ifndef WIN32
608-
if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
609-
#else
610-
if (ioctlsocket(conn->sock, FIONBIO, &on) != 0)
611-
#endif
612-
{
613-
printfPQExpBuffer(&conn->errorMessage,
614-
"connectMakeNonblocking -- fcntl() failed: errno=%d\n%s\n",
615-
errno, strerror(errno));
616-
return 0;
617-
}
618-
619-
return 1;
620-
}
621-
622597
/* ----------
623598
* connectNoDelay -
624599
* Sets the TCP_NODELAY socket option.
@@ -789,7 +764,7 @@ connectDBStart(PGconn *conn)
789764
* Ewan Mellor <eem21@cam.ac.uk>.
790765
* ---------- */
791766
#if (!defined(WIN32) || defined(WIN32_NON_BLOCKING_CONNECTIONS)) && !defined(USE_SSL)
792-
if (!connectMakeNonblocking(conn))
767+
if (PQsetnonblocking(conn, TRUE) != 0)
793768
goto connect_errReturn;
794769
#endif
795770

@@ -898,7 +873,7 @@ connectDBStart(PGconn *conn)
898873
/* This makes the connection non-blocking, for all those cases which forced us
899874
not to do it above. */
900875
#if (defined(WIN32) && !defined(WIN32_NON_BLOCKING_CONNECTIONS)) || defined(USE_SSL)
901-
if (!connectMakeNonblocking(conn))
876+
if (PQsetnonblocking(conn, TRUE) != 0)
902877
goto connect_errReturn;
903878
#endif
904879

@@ -1720,6 +1695,7 @@ makeEmptyPGconn(void)
17201695
conn->inBuffer = (char *) malloc(conn->inBufSize);
17211696
conn->outBufSize = 8 * 1024;
17221697
conn->outBuffer = (char *) malloc(conn->outBufSize);
1698+
conn->nonblocking = FALSE;
17231699
initPQExpBuffer(&conn->errorMessage);
17241700
initPQExpBuffer(&conn->workBuffer);
17251701
if (conn->inBuffer == NULL ||
@@ -1830,6 +1806,7 @@ closePGconn(PGconn *conn)
18301806
conn->lobjfuncs = NULL;
18311807
conn->inStart = conn->inCursor = conn->inEnd = 0;
18321808
conn->outCount = 0;
1809+
conn->nonblocking = FALSE;
18331810

18341811
}
18351812

0 commit comments

Comments
 (0)