Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9dfdbef

Browse files
committed
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
1 parent d5353ac commit 9dfdbef

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/interfaces/libpq/fe-exec.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.151 2003/10/04 21:05:21 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.152 2003/10/19 21:36:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1336,6 +1336,17 @@ PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
13361336
libpq_gettext("no COPY in progress\n"));
13371337
return -1;
13381338
}
1339+
1340+
/*
1341+
* Check for NOTICE messages coming back from the server. Since the
1342+
* server might generate multiple notices during the COPY, we have to
1343+
* consume those in a reasonably prompt fashion to prevent the comm
1344+
* buffers from filling up and possibly blocking the server.
1345+
*/
1346+
if (!PQconsumeInput(conn))
1347+
return -1; /* I/O failure */
1348+
parseInput(conn);
1349+
13391350
if (nbytes > 0)
13401351
{
13411352
/*

src/interfaces/libpq/fe-misc.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Portions Copyright (c) 1994, Regents of the University of California
2424
*
2525
* IDENTIFICATION
26-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.102 2003/08/08 21:42:55 momjian Exp $
26+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.103 2003/10/19 21:36:41 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -828,7 +828,24 @@ pqSendSome(PGconn *conn, int len)
828828
break;
829829
}
830830

831-
if (pqWait(FALSE, TRUE, conn))
831+
/*
832+
* There are scenarios in which we can't send data because the
833+
* communications channel is full, but we cannot expect the server
834+
* to clear the channel eventually because it's blocked trying to
835+
* send data to us. (This can happen when we are sending a large
836+
* amount of COPY data, and the server has generated lots of
837+
* NOTICE responses.) To avoid a deadlock situation, we must be
838+
* prepared to accept and buffer incoming data before we try
839+
* again. Furthermore, it is possible that such incoming data
840+
* might not arrive until after we've gone to sleep. Therefore,
841+
* we wait for either read ready or write ready.
842+
*/
843+
if (pqReadData(conn) < 0)
844+
{
845+
result = -1; /* error message already set up */
846+
break;
847+
}
848+
if (pqWait(TRUE, TRUE, conn))
832849
{
833850
result = -1;
834851
break;

0 commit comments

Comments
 (0)