Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf0ae1e8

Browse files
committed
When closure of the backend connection is detected during pqFlush,
do the right thing: look for a NOTICE message from the backend before weclose our side of the socket. 6.4 libpq did not reliably print the backend'shara-kiri message, 'The Postmaster has informed me ...', because it onlydid the right thing if connection closure was detected during a readattempt instead of a write attempt.
1 parent615e77e commitf0ae1e8

File tree

2 files changed

+70
-20
lines changed

2 files changed

+70
-20
lines changed

‎src/interfaces/libpq/fe-exec.c

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.80 1999/05/25 16:15:12 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.81 1999/05/28 01:54:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -47,6 +47,7 @@ const char *const pgresStatus[] = {
4747

4848
staticintaddTuple(PGresult*res,PGresAttValue*tup);
4949
staticvoidparseInput(PGconn*conn);
50+
staticvoidhandleSendFailure(PGconn*conn);
5051
staticintgetRowDescriptions(PGconn*conn);
5152
staticintgetAnotherTuple(PGconn*conn,intbinary);
5253
staticintgetNotify(PGconn*conn);
@@ -433,18 +434,53 @@ PQsendQuery(PGconn *conn, const char *query)
433434

434435
/* send the query to the backend; */
435436
/* the frontend-backend protocol uses 'Q' to designate queries */
436-
if (pqPutnchar("Q",1,conn))
437-
return0;
438-
if (pqPuts(query,conn))
439-
return0;
440-
if (pqFlush(conn))
437+
if (pqPutnchar("Q",1,conn)||
438+
pqPuts(query,conn)||
439+
pqFlush(conn))
440+
{
441+
handleSendFailure(conn);
441442
return0;
443+
}
442444

443445
/* OK, it's launched! */
444446
conn->asyncStatus=PGASYNC_BUSY;
445447
return1;
446448
}
447449

450+
/*
451+
* handleSendFailure: try to clean up after failure to send command.
452+
*
453+
* Primarily, what we want to accomplish here is to process an async
454+
* NOTICE message that the backend might have sent just before it died.
455+
*
456+
* NOTE: this routine should only be called in PGASYNC_IDLE state.
457+
*/
458+
459+
staticvoid
460+
handleSendFailure(PGconn*conn)
461+
{
462+
/* Preserve the error message emitted by the failing output routine */
463+
char*svErrMsg=strdup(conn->errorMessage);
464+
465+
/*
466+
* Accept any available input data, ignoring errors. Note that if
467+
* pqReadData decides the backend has closed the channel, it will
468+
* close our side of the socket --- that's just what we want here.
469+
*/
470+
while (pqReadData(conn)>0)
471+
/* loop until no more data readable */ ;
472+
473+
/*
474+
* Parse any available input messages. Since we are in PGASYNC_IDLE
475+
* state, only NOTICE and NOTIFY messages will be eaten.
476+
*/
477+
parseInput(conn);
478+
479+
/* Restore error message generated by output routine, if any. */
480+
if (*svErrMsg!='\0')
481+
strcpy(conn->errorMessage,svErrMsg);
482+
free(svErrMsg);
483+
}
448484

449485
/*
450486
* Consume any available input from the backend
@@ -1399,31 +1435,44 @@ PQfn(PGconn *conn,
13991435
/* clear the error string */
14001436
conn->errorMessage[0]='\0';
14011437

1402-
if (pqPuts("F ",conn))/* function */
1403-
returnNULL;
1404-
if (pqPutInt(fnid,4,conn))/*function id */
1405-
returnNULL;
1406-
if (pqPutInt(nargs,4,conn))/* # of args */
1438+
if (pqPuts("F ",conn)||/* function */
1439+
pqPutInt(fnid,4,conn)||/* function id */
1440+
pqPutInt(nargs,4,conn))/*# of args */
1441+
{
1442+
handleSendFailure(conn);
14071443
returnNULL;
1444+
}
14081445

14091446
for (i=0;i<nargs;++i)
14101447
{/* len.int4 + contents */
14111448
if (pqPutInt(args[i].len,4,conn))
1449+
{
1450+
handleSendFailure(conn);
14121451
returnNULL;
1452+
}
14131453

14141454
if (args[i].isint)
14151455
{
14161456
if (pqPutInt(args[i].u.integer,4,conn))
1457+
{
1458+
handleSendFailure(conn);
14171459
returnNULL;
1460+
}
14181461
}
14191462
else
14201463
{
14211464
if (pqPutnchar((char*)args[i].u.ptr,args[i].len,conn))
1465+
{
1466+
handleSendFailure(conn);
14221467
returnNULL;
1468+
}
14231469
}
14241470
}
14251471
if (pqFlush(conn))
1472+
{
1473+
handleSendFailure(conn);
14261474
returnNULL;
1475+
}
14271476

14281477
for (;;)
14291478
{

‎src/interfaces/libpq/fe-misc.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
*
2626
* IDENTIFICATION
27-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.24 1999/05/25 16:15:13 momjian Exp $
27+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.25 1999/05/28 01:54:53 tgl Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -471,7 +471,6 @@ pqFlush(PGconn *conn)
471471
/* Prevent being SIGPIPEd if backend has closed the connection. */
472472
#ifndefWIN32
473473
pqsigfuncoldsighandler=pqsignal(SIGPIPE,SIG_IGN);
474-
475474
#endif
476475

477476
intsent=send(conn->sock,ptr,len,0);
@@ -498,6 +497,7 @@ pqFlush(PGconn *conn)
498497
caseEWOULDBLOCK:
499498
break;
500499
#endif
500+
501501
caseEPIPE:
502502
#ifdefECONNRESET
503503
caseECONNRESET:
@@ -506,14 +506,15 @@ pqFlush(PGconn *conn)
506506
"pqFlush() -- backend closed the channel unexpectedly.\n"
507507
"\tThis probably means the backend terminated abnormally"
508508
" before or while processing the request.\n");
509-
conn->status=CONNECTION_BAD;/* No more connection */
510-
#ifdefWIN32
511-
closesocket(conn->sock);
512-
#else
513-
close(conn->sock);
514-
#endif
515-
conn->sock=-1;
509+
/*
510+
* We used to close the socket here, but that's a bad
511+
* idea since there might be unread data waiting
512+
* (typically, a NOTICE message from the backend telling
513+
* us it's committing hara-kiri...). Leave the socket
514+
* open until pqReadData finds no more data can be read.
515+
*/
516516
returnEOF;
517+
517518
default:
518519
sprintf(conn->errorMessage,
519520
"pqFlush() -- couldn't send data: errno=%d\n%s\n",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp