Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f5e4ded

Browse files
committed
Expose PQsocketPoll via libpq
This is useful when connecting to a database asynchronously via PQconnectStart(), since it handles deciding between poll() and select(), and some of the required boilerplate. Tristan Partin, reviewed by Gurjeet Singh, Heikki Linnakangas, Jelte Fennema-Nio, and me. Discussion: http://postgr.es/m/D08WWCPVHKHN.3QELIKZJ2D9RZ@neon.tech
1 parent 3a352df commit f5e4ded

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

doc/src/sgml/libpq.sgml

+39-1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,41 @@ PGconn *PQsetdb(char *pghost,
262262
</listitem>
263263
</varlistentry>
264264

265+
<varlistentry id="libpq-PQsocketPoll">
266+
<term><function>PQsocketPoll</function><indexterm><primary>PQsocketPoll</primary></indexterm></term>
267+
<listitem>
268+
<para>
269+
<indexterm><primary>nonblocking connection</primary></indexterm>
270+
Poll a connection&apos;s underlying socket descriptor retrieved with <xref linkend="libpq-PQsocket"/>.
271+
<synopsis>
272+
int PQsocketPoll(int sock, int forRead, int forWrite, time_t end_time);
273+
</synopsis>
274+
</para>
275+
276+
<para>
277+
This function sets up polling of a file descriptor. The underlying function is either
278+
<function>poll(2)</function> or <function>select(2)</function>, depending on platform
279+
support. The primary use of this function is iterating through the connection sequence
280+
described in the documentation of <xref linkend="libpq-PQconnectStartParams"/>. If
281+
<parameter>forRead</parameter> is specified, the function waits for the socket to be ready
282+
for reading. If <parameter>forWrite</parameter> is specified, the function waits for the
283+
socket to be ready for write. See <literal>POLLIN</literal> and <literal>POLLOUT</literal>
284+
from <function>poll(2)</function>, or <parameter>readfds</parameter> and
285+
<parameter>writefds</parameter> from <function>select(2)</function> for more information. If
286+
<parameter>end_time</parameter> is not <literal>-1</literal>, it specifies the time at which
287+
this function should stop waiting for the condition to be met.
288+
</para>
289+
290+
<para>
291+
The function returns a value greater than <literal>0</literal> if the specified condition
292+
is met, <literal>0</literal> if a timeout occurred, or <literal>-1</literal> if an error
293+
occurred. The error can be retrieved by checking the <literal>errno(3)</literal> value. In
294+
the event <literal>forRead</literal> and <literal>forWrite</literal> are not set, the
295+
function immediately returns a timeout condition.
296+
</para>
297+
</listitem>
298+
</varlistentry>
299+
265300
<varlistentry id="libpq-PQconnectStartParams">
266301
<term><function>PQconnectStartParams</function><indexterm><primary>PQconnectStartParams</primary></indexterm></term>
267302
<term><function>PQconnectStart</function><indexterm><primary>PQconnectStart</primary></indexterm></term>
@@ -358,7 +393,10 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn);
358393
Loop thus: If <function>PQconnectPoll(conn)</function> last returned
359394
<symbol>PGRES_POLLING_READING</symbol>, wait until the socket is ready to
360395
read (as indicated by <function>select()</function>, <function>poll()</function>, or
361-
similar system function).
396+
similar system function). Note that <function>PQsocketPoll</function>
397+
can help reduce boilerplate by abstracting the setup of
398+
<function>select(2)</function> or <function>poll(2)</function> if it is
399+
available on your system.
362400
Then call <function>PQconnectPoll(conn)</function> again.
363401
Conversely, if <function>PQconnectPoll(conn)</function> last returned
364402
<symbol>PGRES_POLLING_WRITING</symbol>, wait until the socket is ready

src/interfaces/libpq/exports.txt

+1
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,4 @@ PQcancelSocket 199
202202
PQcancelErrorMessage 200
203203
PQcancelReset 201
204204
PQcancelFinish 202
205+
PQsocketPoll 203

src/interfaces/libpq/fe-misc.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn);
5555
static int pqSendSome(PGconn *conn, int len);
5656
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite,
5757
time_t end_time);
58-
static int pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time);
5958

6059
/*
6160
* PQlibVersion: return the libpq version number
@@ -1059,7 +1058,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
10591058

10601059
/* We will retry as long as we get EINTR */
10611060
do
1062-
result = pqSocketPoll(conn->sock, forRead, forWrite, end_time);
1061+
result = PQsocketPoll(conn->sock, forRead, forWrite, end_time);
10631062
while (result < 0 && SOCK_ERRNO == EINTR);
10641063

10651064
if (result < 0)
@@ -1083,8 +1082,8 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
10831082
* Timeout is infinite if end_time is -1. Timeout is immediate (no blocking)
10841083
* if end_time is 0 (or indeed, any time before now).
10851084
*/
1086-
static int
1087-
pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time)
1085+
int
1086+
PQsocketPoll(int sock, int forRead, int forWrite, time_t end_time)
10881087
{
10891088
/* We use poll(2) if available, otherwise select(2) */
10901089
#ifdef HAVE_POLL

src/interfaces/libpq/libpq-fe.h

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern "C"
2121
#endif
2222

2323
#include <stdio.h>
24+
#include <time.h>
2425

2526
/*
2627
* postgres_ext.h defines the backend's externally visible types,
@@ -670,6 +671,9 @@ extern int lo_export(PGconn *conn, Oid lobjId, const char *filename);
670671
/* Get the version of the libpq library in use */
671672
extern int PQlibVersion(void);
672673

674+
/* Poll a socket for reading and/or writing with an optional timeout */
675+
extern int PQsocketPoll(int sock, int forRead, int forWrite, time_t end_time);
676+
673677
/* Determine length of multibyte encoded char at *s */
674678
extern int PQmblen(const char *s, int encoding);
675679

0 commit comments

Comments
 (0)