PostgreSQL Source Code  git master
libpq-be-fe-helpers.h File Reference
#include "libpq-fe.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "utils/wait_event.h"
Include dependency graph for libpq-be-fe-helpers.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static void libpqsrv_connect_prepare (void)
 
static void libpqsrv_connect_internal (PGconn *conn, uint32 wait_event_info)
 
static PGconnlibpqsrv_connect (const char *conninfo, uint32 wait_event_info)
 
static PGconnlibpqsrv_connect_params (const char *const *keywords, const char *const *values, int expand_dbname, uint32 wait_event_info)
 
static void libpqsrv_disconnect (PGconn *conn)
 

Function Documentation

◆ libpqsrv_connect()

static PGconn* libpqsrv_connect ( const char *  conninfo,
uint32  wait_event_info 
)
inlinestatic

Definition at line 63 of file libpq-be-fe-helpers.h.

64 {
65  PGconn *conn = NULL;
66 
68 
69  conn = PQconnectStart(conninfo);
70 
71  libpqsrv_connect_internal(conn, wait_event_info);
72 
73  return conn;
74 }
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:859
static void libpqsrv_connect_prepare(void)
static void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)
PGconn * conn
Definition: streamutil.c:54

References conn, libpqsrv_connect_internal(), libpqsrv_connect_prepare(), and PQconnectStart().

Referenced by dblink_connect(), and dblink_get_conn().

◆ libpqsrv_connect_internal()

static void libpqsrv_connect_internal ( PGconn conn,
uint32  wait_event_info 
)
inlinestatic

Definition at line 157 of file libpq-be-fe-helpers.h.

158 {
159  /*
160  * With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do
161  * that here.
162  */
163  if (conn == NULL)
164  {
166  return;
167  }
168 
169  /*
170  * Can't wait without a socket. Note that we don't want to close the libpq
171  * connection yet, so callers can emit a useful error.
172  */
173  if (PQstatus(conn) == CONNECTION_BAD)
174  return;
175 
176  /*
177  * WaitLatchOrSocket() can conceivably fail, handle that case here instead
178  * of requiring all callers to do so.
179  */
180  PG_TRY();
181  {
183 
184  /*
185  * Poll connection until we have OK or FAILED status.
186  *
187  * Per spec for PQconnectPoll, first wait till socket is write-ready.
188  */
189  status = PGRES_POLLING_WRITING;
190  while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED)
191  {
192  int io_flag;
193  int rc;
194 
195  if (status == PGRES_POLLING_READING)
196  io_flag = WL_SOCKET_READABLE;
197 #ifdef WIN32
198 
199  /*
200  * Windows needs a different test while waiting for
201  * connection-made
202  */
203  else if (PQstatus(conn) == CONNECTION_STARTED)
204  io_flag = WL_SOCKET_CONNECTED;
205 #endif
206  else
207  io_flag = WL_SOCKET_WRITEABLE;
208 
210  WL_EXIT_ON_PM_DEATH | WL_LATCH_SET | io_flag,
211  PQsocket(conn),
212  0,
213  wait_event_info);
214 
215  /* Interrupted? */
216  if (rc & WL_LATCH_SET)
217  {
220  }
221 
222  /* If socket is ready, advance the libpq state machine */
223  if (rc & io_flag)
224  status = PQconnectPoll(conn);
225  }
226  }
227  PG_CATCH();
228  {
229  /*
230  * If an error is thrown here, the callers won't call
231  * libpqsrv_disconnect() with a conn, so release resources
232  * immediately.
233  */
235  PQfinish(conn);
236 
237  PG_RE_THROW();
238  }
239  PG_END_TRY();
240 }
#define PG_RE_THROW()
Definition: elog.h:411
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_CATCH(...)
Definition: elog.h:380
void ReleaseExternalFD(void)
Definition: fd.c:1216
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2541
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7195
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4602
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7274
struct Latch * MyLatch
Definition: globals.c:58
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:566
void ResetLatch(Latch *latch)
Definition: latch.c:725
#define WL_SOCKET_READABLE
Definition: latch.h:128
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_LATCH_SET
Definition: latch.h:127
#define WL_SOCKET_CONNECTED
Definition: latch.h:137
#define WL_SOCKET_WRITEABLE
Definition: latch.h:129
@ CONNECTION_STARTED
Definition: libpq-fe.h:68
@ CONNECTION_BAD
Definition: libpq-fe.h:61
PostgresPollingStatusType
Definition: libpq-fe.h:85
@ PGRES_POLLING_OK
Definition: libpq-fe.h:89
@ PGRES_POLLING_READING
Definition: libpq-fe.h:87
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:88
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:86
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121

References CHECK_FOR_INTERRUPTS, conn, CONNECTION_BAD, CONNECTION_STARTED, MyLatch, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQconnectPoll(), PQfinish(), PQsocket(), PQstatus(), ReleaseExternalFD(), ResetLatch(), WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_SOCKET_CONNECTED, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by libpqsrv_connect(), and libpqsrv_connect_params().

◆ libpqsrv_connect_params()

static PGconn* libpqsrv_connect_params ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname,
uint32  wait_event_info 
)
inlinestatic

Definition at line 81 of file libpq-be-fe-helpers.h.

85 {
86  PGconn *conn = NULL;
87 
89 
90  conn = PQconnectStartParams(keywords, values, expand_dbname);
91 
92  libpqsrv_connect_internal(conn, wait_event_info);
93 
94  return conn;
95 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:778

References conn, libpqsrv_connect_internal(), libpqsrv_connect_prepare(), PQconnectStartParams(), and values.

Referenced by connect_pg_server(), and libpqrcv_connect().

◆ libpqsrv_connect_prepare()

static void libpqsrv_connect_prepare ( void  )
inlinestatic

Definition at line 128 of file libpq-be-fe-helpers.h.

129 {
130  /*
131  * We must obey fd.c's limit on non-virtual file descriptors. Assume that
132  * a PGconn represents one long-lived FD. (Doing this here also ensures
133  * that VFDs are closed if needed to make room.)
134  */
135  if (!AcquireExternalFD())
136  {
137 #ifndef WIN32 /* can't write #if within ereport() macro */
138  ereport(ERROR,
139  (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
140  errmsg("could not establish connection"),
141  errdetail("There are too many open files on the local server."),
142  errhint("Raise the server's max_files_per_process and/or \"ulimit -n\" limits.")));
143 #else
144  ereport(ERROR,
145  (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
146  errmsg("could not establish connection"),
147  errdetail("There are too many open files on the local server."),
148  errhint("Raise the server's max_files_per_process setting.")));
149 #endif
150  }
151 }
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool AcquireExternalFD(void)
Definition: fd.c:1163

References AcquireExternalFD(), ereport, errcode(), errdetail(), errhint(), errmsg(), and ERROR.

Referenced by libpqsrv_connect(), and libpqsrv_connect_params().

◆ libpqsrv_disconnect()

static void libpqsrv_disconnect ( PGconn conn)
inlinestatic

Definition at line 104 of file libpq-be-fe-helpers.h.

105 {
106  /*
107  * If no connection was established, we haven't reserved an FD for it (or
108  * already released it). This rule makes it easier to write PG_CATCH()
109  * handlers for this facility's users.
110  *
111  * See also libpqsrv_connect_internal().
112  */
113  if (conn == NULL)
114  return;
115 
117  PQfinish(conn);
118 }

References conn, PQfinish(), and ReleaseExternalFD().

Referenced by connect_pg_server(), createNewConnection(), dblink_connect(), dblink_disconnect(), dblink_exec(), dblink_get_conn(), dblink_record_internal(), dblink_security_check(), disconnect_pg_server(), libpqrcv_connect(), and libpqrcv_disconnect().