aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-misc.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-10-19 21:36:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-10-19 21:36:41 +0000
commit9dfdbef345390124eaf993f6289e8ae796aa6918 (patch)
tree43791a5127da2fb3b166131ae1868ab662ba8cfe /src/interfaces/libpq/fe-misc.c
parentd5353acbc37e8043172855f8c148c96ae1694e61 (diff)
downloadpostgresql-9dfdbef345390124eaf993f6289e8ae796aa6918.tar.gz
postgresql-9dfdbef345390124eaf993f6289e8ae796aa6918.zip
Adjust libpq to avoid deadlock when both client and server want to send
data, and both have filled the transmission buffers. One scenario where this can happen was illustrated here: http://archives.postgresql.org/pgsql-hackers/2003-04/msg00979.php
Diffstat (limited to 'src/interfaces/libpq/fe-misc.c')
-rw-r--r--src/interfaces/libpq/fe-misc.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index d71473d514a..4349a4e05aa 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -23,7 +23,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.102 2003/08/08 21:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.103 2003/10/19 21:36:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -828,7 +828,24 @@ pqSendSome(PGconn *conn, int len)
break;
}
- if (pqWait(FALSE, TRUE, conn))
+ /*
+ * There are scenarios in which we can't send data because the
+ * communications channel is full, but we cannot expect the server
+ * to clear the channel eventually because it's blocked trying to
+ * send data to us. (This can happen when we are sending a large
+ * amount of COPY data, and the server has generated lots of
+ * NOTICE responses.) To avoid a deadlock situation, we must be
+ * prepared to accept and buffer incoming data before we try
+ * again. Furthermore, it is possible that such incoming data
+ * might not arrive until after we've gone to sleep. Therefore,
+ * we wait for either read ready or write ready.
+ */
+ if (pqReadData(conn) < 0)
+ {
+ result = -1; /* error message already set up */
+ break;
+ }
+ if (pqWait(TRUE, TRUE, conn))
{
result = -1;
break;