aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/pqcomm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/pqcomm.c')
-rw-r--r--src/backend/libpq/pqcomm.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 4c7b1e7bfdf..4cd6d6dfbb9 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -54,6 +54,9 @@
*/
#include "postgres.h"
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <signal.h>
#include <fcntl.h>
#include <grp.h>
@@ -1921,3 +1924,40 @@ pq_settcpusertimeout(int timeout, Port *port)
return STATUS_OK;
}
+
+/*
+ * Check if the client is still connected.
+ */
+bool
+pq_check_connection(void)
+{
+#if defined(POLLRDHUP)
+ /*
+ * POLLRDHUP is a Linux extension to poll(2) to detect sockets closed by
+ * the other end. We don't have a portable way to do that without
+ * actually trying to read or write data on other systems. We don't want
+ * to read because that would be confused by pipelined queries and COPY
+ * data. Perhaps in future we'll try to write a heartbeat message instead.
+ */
+ struct pollfd pollfd;
+ int rc;
+
+ pollfd.fd = MyProcPort->sock;
+ pollfd.events = POLLOUT | POLLIN | POLLRDHUP;
+ pollfd.revents = 0;
+
+ rc = poll(&pollfd, 1, 0);
+
+ if (rc < 0)
+ {
+ ereport(COMMERROR,
+ (errcode_for_socket_access(),
+ errmsg("could not poll socket: %m")));
+ return false;
+ }
+ else if (rc == 1 && (pollfd.revents & (POLLHUP | POLLRDHUP)))
+ return false;
+#endif
+
+ return true;
+}