Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f5e4ded

Browse filesBrowse 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
Copy full SHA for f5e4ded

File tree

Expand file treeCollapse file tree

4 files changed

+47
-5
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+47
-5
lines changed

‎doc/src/sgml/libpq.sgml

Copy file name to clipboardExpand all lines: doc/src/sgml/libpq.sgml
+39-1Lines changed: 39 additions & 1 deletion
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

Copy file name to clipboardExpand all lines: src/interfaces/libpq/exports.txt
+1Lines changed: 1 addition & 0 deletions
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

Copy file name to clipboardExpand all lines: src/interfaces/libpq/fe-misc.c
+3-4Lines changed: 3 additions & 4 deletions
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

Copy file name to clipboardExpand all lines: src/interfaces/libpq/libpq-fe.h
+4Lines changed: 4 additions & 0 deletions
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.