0006-WIP-Process-die-interrupts-while-reading-writing-fro.patch
text/x-patch
Filename: 0006-WIP-Process-die-interrupts-while-reading-writing-fro.patch
Type: text/x-patch
Part: 5
Patch
Format: unified
Series: patch 0006
| File | + | − |
|---|---|---|
| src/backend/libpq/be-secure.c | 14 | 16 |
| src/backend/libpq/be-secure-openssl.c | 5 | 2 |
| src/backend/tcop/postgres.c | 25 | 0 |
| src/include/tcop/tcopprot.h | 1 | 0 |
>From d0887c4db8b38ffb27061e7f7709d0f9e2402392 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sun, 28 Sep 2014 00:22:39 +0200
Subject: [PATCH 6/6] WIP: Process 'die' interrupts while reading/writing from
a socket.
Per discussion with Kyotaro HORIGUCHI and Heikki Linnakangas
---
src/backend/libpq/be-secure-openssl.c | 7 +++++--
src/backend/libpq/be-secure.c | 30 ++++++++++++++----------------
src/backend/tcop/postgres.c | 25 +++++++++++++++++++++++++
src/include/tcop/tcopprot.h | 1 +
4 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 3a70f43..1fc4c76 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -634,10 +634,13 @@ wloop:
/* Don't retry if the socket is in nonblocking mode. */
if (port->noblock)
break;
+
/*
- * XXX: We'll, at some later point, likely want to add interrupt
- * processing here.
+ * Check for interrupts here, in addition to secure_write(),
+ * because a interrupted write in secure_raw_write() will only
+ * return here, not secure_write().
*/
+ ProcessClientWriteInterrupt(true);
goto wloop;
case SSL_ERROR_SYSCALL:
/* leave it to caller to ereport the value of errno */
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 71742a6..cae2955 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -224,16 +224,10 @@ retry:
n = secure_raw_write(port, ptr, len);
}
- /*
- * XXX: We'll, at some later point, likely want to add interrupt
- * processing here.
- */
+ /* Process interrupts that happened while (or before) writing. */
+ ProcessClientWriteInterrupt(!port->noblock && n < 0);
- /*
- * Retry after processing interrupts. This can be triggered even though we
- * don't check for latch set's during writing yet, because SSL
- * renegotiations might have required reading from the socket.
- */
+ /* retry after processing interrupts */
if (n < 0 && errno == EINTR)
{
goto retry;
@@ -262,16 +256,20 @@ wloop:
int w;
int save_errno = errno;
- /*
- * XXX: We'll, at some later point, likely want to add interrupt
- * processing here. If set we'd not retry directly, but return. That
- * way we don't do anything while (possibly) inside a ssl library.
- */
w = WaitLatchOrSocket(MyLatch,
- WL_SOCKET_WRITEABLE,
+ WL_LATCH_SET | WL_SOCKET_WRITEABLE,
port->sock, 0);
- if (w & WL_SOCKET_WRITEABLE)
+ if (w & WL_LATCH_SET)
+ {
+ ResetLatch(&MyProc->procLatch);
+ /*
+ * Force a return, so interrupts can be processed when not
+ * (possibly) underneath a ssl library.
+ */
+ errno = EINTR;
+ }
+ else if (w & WL_SOCKET_WRITEABLE)
{
goto wloop;
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c4e3a61..0e5b317 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -519,10 +519,35 @@ ProcessClientReadInterrupt(void)
if (notifyInterruptPending)
ProcessNotifyInterrupt();
}
+ else if (ProcDiePending)
+ {
+ /*
+ * We're dying. It's safe (and sane) to handle that now.
+ */
+ CHECK_FOR_INTERRUPTS();
+ }
errno = save_errno;
}
+void
+ProcessClientWriteInterrupt(bool blocked)
+{
+ /*
+ * We only want to process the interrupt here if socket writes are
+ * blocking to increase the chance to get an error message to the
+ * client. If we're not blocked there'll soon be a
+ * CHECK_FOR_INTERRUPTS(). But if we're blocked we'll never get out of
+ * that situation if the client has died.
+ */
+ if (ProcDiePending && blocked)
+ {
+ /*
+ * We're dying. It's safe (and sane) to handle that now.
+ */
+ CHECK_FOR_INTERRUPTS();
+ }
+}
/*
* Do raw parsing (only).
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index fe8c725..fc04a3e 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -68,6 +68,7 @@ extern void FloatExceptionHandler(SIGNAL_ARGS) __attribute__((noreturn));
extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1
* handler */
extern void ProcessClientReadInterrupt(void);
+extern void ProcessClientWriteInterrupt(bool blocked);
extern void process_postgres_switches(int argc, char *argv[],
GucContext ctx, const char **dbname);
--
2.2.1.212.gc5b9256