0001-server-notify-fix.patch
text/x-diff
Filename: 0001-server-notify-fix.patch
Type: text/x-diff
Part: 0
Message:
Re: NOTIFY does not work as expected
Patch
Format: unified
Series: patch 0001
| File | + | − |
|---|---|---|
| src/backend/libpq/be-secure.c | 28 | 10 |
| src/backend/tcop/postgres.c | 7 | 17 |
| src/include/tcop/tcopprot.h | 2 | 2 |
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index d349d7c..2880736 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -145,6 +145,16 @@ secure_read(Port *port, void *ptr, size_t len)
ssize_t n;
int waitfor;
+ /*
+ * We might already have a pending interrupt condition to deal with. If
+ * the process latch is set, that would cause us to fall through the read
+ * and handle the condition below --- but the latch might have been
+ * cleared since the condition interrupt happened. This is cheap enough
+ * (if there's nothing to do) that it's not worth being too tense about
+ * avoiding it.
+ */
+ ProcessClientReadInterrupt();
+
retry:
#ifdef USE_SSL
waitfor = 0;
@@ -197,7 +207,7 @@ retry:
if (event.events & WL_LATCH_SET)
{
ResetLatch(MyLatch);
- ProcessClientReadInterrupt(true);
+ ProcessClientReadInterrupt();
/*
* We'll retry the read. Most likely it will return immediately
@@ -209,11 +219,10 @@ retry:
}
/*
- * Process interrupts that happened while (or before) receiving. Note that
- * we signal that we're not blocking, which will prevent some types of
- * interrupts from being processed.
+ * Process interrupts that happened during a successful (or hard-failed)
+ * read.
*/
- ProcessClientReadInterrupt(false);
+ ProcessClientReadInterrupt();
return n;
}
@@ -248,6 +257,16 @@ secure_write(Port *port, void *ptr, size_t len)
ssize_t n;
int waitfor;
+ /*
+ * We might already have a pending interrupt condition to deal with. If
+ * the process latch is set, that would cause us to fall through the write
+ * and handle the condition below --- but the latch might have been
+ * cleared since the condition interrupt happened. This is cheap enough
+ * (if there's nothing to do) that it's not worth being too tense about
+ * avoiding it.
+ */
+ ProcessClientWriteInterrupt();
+
retry:
waitfor = 0;
#ifdef USE_SSL
@@ -283,7 +302,7 @@ retry:
if (event.events & WL_LATCH_SET)
{
ResetLatch(MyLatch);
- ProcessClientWriteInterrupt(true);
+ ProcessClientWriteInterrupt();
/*
* We'll retry the write. Most likely it will return immediately
@@ -295,11 +314,10 @@ retry:
}
/*
- * Process interrupts that happened while (or before) sending. Note that
- * we signal that we're not blocking, which will prevent some types of
- * interrupts from being processed.
+ * Process interrupts that happened during a successful (or hard-failed)
+ * write.
*/
- ProcessClientWriteInterrupt(false);
+ ProcessClientWriteInterrupt();
return n;
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index e4c6e3d..57f8075 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -315,7 +315,7 @@ interactive_getc(void)
c = getc(stdin);
- ProcessClientReadInterrupt(true);
+ ProcessClientReadInterrupt();
return c;
}
@@ -520,13 +520,12 @@ ReadCommand(StringInfo inBuf)
/*
* ProcessClientReadInterrupt() - Process interrupts specific to client reads
*
- * This is called just after low-level reads. That might be after the read
- * finished successfully, or it was interrupted via interrupt.
+ * This is called just before and after low-level reads.
*
* Must preserve errno!
*/
void
-ProcessClientReadInterrupt(bool blocked)
+ProcessClientReadInterrupt(void)
{
int save_errno = errno;
@@ -543,7 +542,7 @@ ProcessClientReadInterrupt(bool blocked)
if (notifyInterruptPending)
ProcessNotifyInterrupt();
}
- else if (ProcDiePending && blocked)
+ else if (ProcDiePending)
{
/*
* We're dying. It's safe (and sane) to handle that now.
@@ -557,25 +556,16 @@ ProcessClientReadInterrupt(bool blocked)
/*
* ProcessClientWriteInterrupt() - Process interrupts specific to client writes
*
- * This is called just after low-level writes. That might be after the read
- * finished successfully, or it was interrupted via interrupt. 'blocked' tells
- * us whether the
+ * This is called just before and after low-level writes.
*
* Must preserve errno!
*/
void
-ProcessClientWriteInterrupt(bool blocked)
+ProcessClientWriteInterrupt(void)
{
int save_errno = errno;
- /*
- * 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)
+ if (ProcDiePending)
{
/*
* We're dying. It's safe (and sane) to handle that now. But we don't
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 63b4e48..8051d9a 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -71,8 +71,8 @@ extern void StatementCancelHandler(SIGNAL_ARGS);
extern void FloatExceptionHandler(SIGNAL_ARGS) pg_attribute_noreturn();
extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1
* handler */
-extern void ProcessClientReadInterrupt(bool blocked);
-extern void ProcessClientWriteInterrupt(bool blocked);
+extern void ProcessClientReadInterrupt(void);
+extern void ProcessClientWriteInterrupt(void);
extern void process_postgres_switches(int argc, char *argv[],
GucContext ctx, const char **dbname);