diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 41ec1ad..fbb4c47 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -34,7 +34,7 @@
 #include "libpq/libpq.h"
 #include "tcop/tcopprot.h"
 #include "utils/memutils.h"
-
+#include "miscadmin.h"
 
 char	   *ssl_cert_file;
 char	   *ssl_key_file;
@@ -140,6 +140,10 @@ secure_read(Port *port, void *ptr, size_t len)
 	return n;
 }
 
+/*
+ *  Read data from socket.
+ *  This emulates blocking behavior using non-blocking sockets.
+ */
 ssize_t
 secure_raw_read(Port *port, void *ptr, size_t len)
 {
@@ -147,8 +151,34 @@ secure_raw_read(Port *port, void *ptr, size_t len)
 
 	prepare_for_client_read();
 
-	n = recv(port->sock, ptr, len, 0);
+	if (port->noblock)
+		n = recv(port->sock, ptr, len, 0);
+	else
+	{
+		do
+		{
+			fd_set rfds;
+
+			FD_ZERO(&rfds);
+			FD_SET(port->sock, &rfds);
 
+			/*
+			 * In contrast to secure_raw_write, this section runs with
+			 * ImmediateInterruptOK = true so we can wait forever in
+			 * select.
+			 */
+			n = select(port->sock + 1, &rfds, NULL, NULL, NULL);
+			if (n < 0) break;
+
+			n = recv(port->sock, ptr, len, 0);
+
+			/*
+			 * We should have something to read here so EAGAIN/EWOULDBLOCK is
+			 * likey not to be seen. But we check them here not to return
+			 * these error numbers for blocking sockets for the caller.
+			 */
+		} while (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK));
+	}
 	client_read_ended();
 
 	return n;
@@ -178,5 +208,77 @@ secure_write(Port *port, void *ptr, size_t len)
 ssize_t
 secure_raw_write(Port *port, const void *ptr, size_t len)
 {
-	return send(port->sock, ptr, len, 0);
+	int ret = 0;
+
+	/*
+	 * Port socket is always in non-blocking mode. See StreamConnection for
+	 * the details.
+	 */
+	ret = send(port->sock, ptr, len, 0);
+
+	/* We can return here regardless of blocking mode in the most cases */
+	if (port->noblock || ret > 0 || len == 0)
+		return ret;
+
+	/* Here, we shold block waiting for the room in send buffer. */
+	while(ret < 1 && !ProcDiePending)
+	{
+		fd_set wfds;
+		struct timeval tv;
+		int i = 0;
+
+		FD_ZERO(&wfds);
+		tv.tv_usec = 0;
+
+		/*
+		 * We may get terminate signal (SIGTERM) during write blocking. If we
+		 * check ProcDiePending then wait by select indefinitely, SIGTERM
+		 * comes after the check and before the select will be pending and we
+		 * should wait the second SIGTERM. So we periodically wake up to check
+		 * ProcDiePending in order to catch the signal surely.  The timeout
+		 * for the select is the maximum delay of handling the signal. 1
+		 * seconds groundlessly seems to be appropreate.
+		 */
+		do
+		{
+			FD_SET(port->sock, &wfds);
+			tv.tv_sec = 1;
+			tv.tv_usec = 0;
+
+			ret = select(port->sock + 1, NULL, &wfds, NULL, &tv);
+		} while (!ProcDiePending && ret == 0);
+
+		if (ProcDiePending || ret < 0)
+			break;
+
+		ret = send(port->sock, ptr, len, 0);
+		if (ProcDiePending)
+			break;
+		if (ret < 0)
+		{
+			if (errno != EAGAIN && errno != EWOULDBLOCK)
+				break;
+
+			/*
+			 * This loop might run a busy loop if send(2) returned EAGAIN or
+			 * EWOULDBLOCK after select(2) returned normally. Sleep expressly
+			 * to avoid the busy loop.
+			 */
+			pg_usleep(200000L); /* 200 ms */
+			ret = 0;
+		}
+	}
+
+	if (ProcDiePending)
+	{
+		/*
+		 * Allow to terminate this backend. ClientConnectionLost prevents any
+		 * more bytes including error messages from being sent to
+		 * client. errno is set in order to teach ssl layer not to retry.
+		 */
+		ClientConnectionLost = 1;
+		errno = ECONNRESET;
+	}
+	
+	return ret;
 }
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index c92851e..8387d6a 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -718,6 +718,17 @@ StreamConnection(pgsocket server_fd, Port *port)
 		(void) pq_setkeepalivescount(tcp_keepalives_count, port);
 	}
 
+	/*
+	 * Put this socket to non-blocking mode. Blocking behavior is emulated in
+	 * secure_write() and secure_read().
+	 * Use COMMERROR on failure, because ERROR would try to send the error to
+	 * the client, which might require changing the mode again, leading to
+	 * infinite recursion.
+	 */
+	if (!pg_set_noblock(port->sock))
+		ereport(COMMERROR,
+				(errmsg("could not set socket to nonblocking mode: %m")));
+
 	return STATUS_OK;
 }
 
@@ -792,27 +803,6 @@ TouchSocketFiles(void)
 static void
 pq_set_nonblocking(bool nonblocking)
 {
-	if (MyProcPort->noblock == nonblocking)
-		return;
-
-	/*
-	 * Use COMMERROR on failure, because ERROR would try to send the error to
-	 * the client, which might require changing the mode again, leading to
-	 * infinite recursion.
-	 */
-	if (nonblocking)
-	{
-		if (!pg_set_noblock(MyProcPort->sock))
-			ereport(COMMERROR,
-					(errmsg("could not set socket to nonblocking mode: %m")));
-	}
-	else
-	{
-		if (!pg_set_block(MyProcPort->sock))
-			ereport(COMMERROR,
-					(errmsg("could not set socket to blocking mode: %m")));
-	}
-
 	MyProcPort->noblock = nonblocking;
 }
 
@@ -1249,34 +1239,38 @@ internal_flush(void)
 
 		if (r <= 0)
 		{
-			if (errno == EINTR)
-				continue;		/* Ok if we were interrupted */
-
-			/*
-			 * Ok if no data writable without blocking, and the socket is in
-			 * non-blocking mode.
-			 */
-			if (errno == EAGAIN ||
-				errno == EWOULDBLOCK)
+			if (!ClientConnectionLost)
 			{
+				if (errno == EINTR)
+					continue;		/* Ok if we were interrupted */
+
+				/*
+				 * Ok if no data writable without blocking, and the socket is in
+				 * non-blocking mode.
+				 */
+				if (errno == EAGAIN ||
+					errno == EWOULDBLOCK)
+				{
 				return 0;
-			}
-
-			/*
-			 * Careful: an ereport() that tries to write to the client would
-			 * cause recursion to here, leading to stack overflow and core
-			 * dump!  This message must go *only* to the postmaster log.
-			 *
-			 * If a client disconnects while we're in the midst of output, we
-			 * might write quite a bit of data before we get to a safe query
-			 * abort point.  So, suppress duplicate log messages.
-			 */
-			if (errno != last_reported_send_errno)
-			{
-				last_reported_send_errno = errno;
-				ereport(COMMERROR,
-						(errcode_for_socket_access(),
-						 errmsg("could not send data to client: %m")));
+				}
+
+				/*
+				 * Careful: an ereport() that tries to write to the client
+				 * would cause recursion to here, leading to stack overflow
+				 * and core dump!  This message must go *only* to the
+				 * postmaster log.
+				 *
+				 * If a client disconnects while we're in the midst of output,
+				 * we might write quite a bit of data before we get to a safe
+				 * query abort point.  So, suppress duplicate log messages.
+				 */
+				if (errno != last_reported_send_errno)
+				{
+					last_reported_send_errno = errno;
+					ereport(COMMERROR,
+							(errcode_for_socket_access(),
+							 errmsg("could not send data to client: %m")));
+				}
 			}
 
 			/*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 5d32de6..d979191 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -5789,6 +5789,13 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
 		*dest = s;
 
 		/*
+		 * We didn't inherit emulated blocking mode but port socket should be
+		 * always in nonblocking mode. pg_set_noblock() on win32 backend won't
+		 * return error.
+		 */
+		pg_set_noblock(s);
+
+		/*
 		 * To make sure we don't get two references to the same socket, close
 		 * the original one. (This would happen when inheritance actually
 		 * works..
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 7b5480f..1d252e7 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2840,8 +2840,16 @@ ProcessInterrupts(void)
 		ImmediateInterruptOK = false;	/* not idle anymore */
 		DisableNotifyInterrupt();
 		DisableCatchupInterrupt();
-		/* As in quickdie, don't risk sending to client during auth */
-		if (ClientAuthInProgress && whereToSendOutput == DestRemote)
+		/*
+		 *  As in quickdie, don't risk sending to client during auth. In
+		 *  addition to that, don't try to send any more to client if current
+		 *  connection is marked as ClientConnectionLost. It will lead to
+		 *  protocol violation if the truth is that the connection is living
+		 *  and amid sending data. Such case will occur if this backend was
+		 *  terminated during waiting for query result to be sent.
+		 */
+		if ((ClientAuthInProgress && whereToSendOutput == DestRemote) ||
+			ClientConnectionLost)
 			whereToSendOutput = DestNone;
 		if (IsAutoVacuumWorkerProcess())
 			ereport(FATAL,
