Fix do_query() hangs after close message.
authorTatsuo Ishii <ishii@postgresql.org>
Fri, 27 Jan 2017 07:12:47 +0000 (16:12 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Fri, 27 Jan 2017 07:17:54 +0000 (16:17 +0900)
This is an en-bug in 3.6.1.

If an extend query appears right after a close message, do_query() is
called to check system catalogs, it hangs because it expects to read
pending data. This is caused by being mistakenly set the pending flag
after Close().

Back patch to 3.6-stable and 3.5-stable.

src/context/pool_session_context.c
src/protocol/pool_proto_modules.c

index 10608679d12dab8603baed056301b6f186b3e5c8..773ff787921e3e85ca6ecacc94259e240484d42d 100644 (file)
@@ -1000,6 +1000,9 @@ void pool_set_pending_response(void)
                ereport(ERROR,
                                (errmsg("pool_set_pending_response: session context is not initialized")));
 
+       ereport(DEBUG1,
+                       (errmsg("pool_set_pending_response")));
+
        session_context->is_pending_response = true;
 }
 
@@ -1012,6 +1015,9 @@ void pool_unset_pending_response(void)
                ereport(ERROR,
                                (errmsg("pool_unset_pending_response: session context is not initialized")));
 
+       ereport(DEBUG1,
+                       (errmsg("pool_unset_pending_response")));
+
        session_context->is_pending_response = false;
 }
 
index 9d05d82e771f0c692bebd45186506e334450f974..63822507326047b1bcfbe71e74ab742b2e96d483 100644 (file)
@@ -1517,6 +1517,10 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
                pmsg = pool_pending_messages_create('C', len, contents);
                pool_pending_message_add(pmsg);
                pool_unset_query_in_progress();
+               /*
+                * Remeber that we send flush or sync message to backend.
+                */
+               pool_unset_pending_response();
        }
 
        return POOL_CONTINUE;
@@ -2420,7 +2424,6 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
                        if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync())
                                pool_set_query_in_progress();
                        status = Close(frontend, backend, len, contents);
-                       pool_set_pending_response();
                        break;
 
                case 'D':       /* Describe */