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

Commite6725d1

Browse files
committed
Add explicit buffering in backend libpq, to compensate for
buffering lost by not going through stdio anymore for client I/O.
1 parent13c7c18 commite6725d1

File tree

5 files changed

+195
-100
lines changed

5 files changed

+195
-100
lines changed

‎src/backend/commands/copy.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.67 1999/01/17 06:18:15 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.68 1999/01/23 22:27:26 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -303,9 +303,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
303303
}
304304
elseif (!from&& !binary)
305305
{
306-
CopySendData("\\.\n",3,fp);
307-
if (IsUnderPostmaster)
308-
pq_flush();
306+
CopySendData("\\.\n",3,fp);
309307
}
310308
}
311309
}

‎src/backend/libpq/pqcomm.c

Lines changed: 126 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,40 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: pqcomm.c,v 1.63 1999/01/17 06:18:26 momjian Exp $
8+
* $Id: pqcomm.c,v 1.64 1999/01/23 22:27:28 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
1212
/*
1313
* INTERFACE ROUTINES
14-
*pq_init- initialize libpq
14+
*pq_init- initialize libpq
1515
*pq_getport- return the PGPORT setting
1616
*pq_close- close input / output connections
1717
*pq_flush- flush pending output
18+
*pq_recvbuf- load some bytes into the input buffer
1819
*pq_getstr- get a null terminated string from connection
19-
*pq_getchar- get 1 character from connection
20-
*pq_peekchar- peek atfirst characterin connection
20+
*pq_getchar- get 1 character from connection
21+
*pq_peekchar- peek atnext characterfrom connection
2122
*pq_getnchar- get n characters from connection, and null-terminate
2223
*pq_getint- get an integer from connection
23-
*pq_putchar- send 1 character to connection
24+
*pq_putchar- send 1 character to connection
2425
*pq_putstr- send a null terminated string to connection
2526
*pq_putnchar- send n characters to connection
2627
*pq_putint- send an integer to connection
27-
*pq_putncharlen- send n characters to connection
28+
*pq_putncharlen- send n characters to connection
2829
* (also send an int header indicating
2930
* the length)
3031
*pq_getinaddr- initialize address from host and port number
3132
*pq_getinserv- initialize address from host and service name
3233
*
33-
*StreamDoUnlink- Shutdown UNIX socketconnectioin
34-
*StreamServerPort- Opensock stream
35-
*StreamConnection- Create new connection with client
36-
*StreamClose- Close a client/backend connection
34+
*StreamDoUnlink- Shutdown UNIX socketconnection
35+
*StreamServerPort- Opensocket stream
36+
*StreamConnection- Create new connection with client
37+
*StreamClose- Close a client/backend connection
3738
*
3839
* NOTES
39-
* Frontend is nowcompletey in interfaces/libpq, and no
40-
* functions from this fileis used.
40+
* Frontend is nowcompletely in interfaces/libpq, and no
41+
* functions from this fileare used there.
4142
*
4243
*/
4344
#include"postgres.h"
@@ -79,13 +80,22 @@
7980

8081
externFILE*debug_port;/* in util.c */
8182

83+
/*
84+
* Buffers
85+
*/
86+
charPqSendBuffer[PQ_BUFFER_SIZE];
87+
charPqRecvBuffer[PQ_BUFFER_SIZE];
88+
intPqSendPointer,PqRecvPointer,PqRecvLength;
89+
90+
8291
/* --------------------------------
8392
*pq_init - open portal file descriptors
8493
* --------------------------------
8594
*/
8695
void
8796
pq_init(intfd)
8897
{
98+
PqSendPointer=PqRecvPointer=PqRecvLength=0;
8999
PQnotifies_init();
90100
if (getenv("LIBPQ_DEBUG"))
91101
debug_port=stderr;
@@ -94,40 +104,40 @@ pq_init(int fd)
94104
/* -------------------------
95105
* pq_getchar()
96106
*
97-
* get a character from the input file,
98-
*
107+
* get a character from the input file, or EOF if trouble
108+
* --------------------------------
99109
*/
100110

101111
int
102112
pq_getchar(void)
103113
{
104-
charc;
105-
106-
while (recv(MyProcPort->sock,&c,1,0)!=1) {
107-
if (errno!=EINTR)
108-
returnEOF;/* Not interrupted, so something went wrong */
114+
while (PqRecvPointer >=PqRecvLength)
115+
{
116+
if (pq_recvbuf())/* If nothing in buffer, then recv some */
117+
returnEOF;/* Failed to recv data */
109118
}
110-
111-
returnc;
119+
returnPqRecvBuffer[PqRecvPointer++];
112120
}
113121

114-
/*
122+
/* -------------------------
123+
* pq_peekchar()
124+
*
125+
* get a character from the connection, but leave it in the buffer
126+
* to be read again
115127
* --------------------------------
116-
* pq_peekchar - get 1 character from connection, but leave it in the stream
117128
*/
118-
int
119-
pq_peekchar(void) {
120-
charc;
121129

122-
while (recv(MyProcPort->sock,&c,1,MSG_PEEK)!=1) {
123-
if (errno!=EINTR)
124-
returnEOF;/* Not interrupted, so something went wrong */
130+
int
131+
pq_peekchar(void)
132+
{
133+
while (PqRecvPointer >=PqRecvLength)
134+
{
135+
if (pq_recvbuf())/* If nothing in buffer, then recv some */
136+
returnEOF;/* Failed to recv data */
125137
}
126-
127-
returnc;
138+
/* Note we don't bump the pointer... */
139+
returnPqRecvBuffer[PqRecvPointer];
128140
}
129-
130-
131141

132142
/* --------------------------------
133143
*pq_getport - return the PGPORT setting
@@ -150,18 +160,91 @@ pq_getport()
150160
void
151161
pq_close()
152162
{
153-
close(MyProcPort->sock);
163+
close(MyProcPort->sock);
154164
PQnotifies_init();
155165
}
156166

157167
/* --------------------------------
158168
*pq_flush - flush pending output
169+
*
170+
*returns 0 if OK, EOF if trouble
159171
* --------------------------------
160172
*/
161-
void
173+
int
162174
pq_flush()
163175
{
164-
/* Not supported/required? */
176+
char*bufptr=PqSendBuffer;
177+
char*bufend=PqSendBuffer+PqSendPointer;
178+
179+
while (bufptr<bufend)
180+
{
181+
intr=send(MyProcPort->sock,bufptr,bufend-bufptr,0);
182+
if (r <=0)
183+
{
184+
if (errno==EINTR)
185+
continue;/* Ok if we were interrupted */
186+
/* We would like to use elog() here, but cannot because elog
187+
* tries to write to the client, which would cause a recursive
188+
* flush attempt! So just write it out to the postmaster log.
189+
*/
190+
fprintf(stderr,"pq_flush: send() failed, errno %d\n",errno);
191+
/* We drop the buffered data anyway so that processing
192+
* can continue, even though we'll probably quit soon.
193+
*/
194+
PqSendPointer=0;
195+
returnEOF;
196+
}
197+
bufptr+=r;
198+
}
199+
PqSendPointer=0;
200+
return0;
201+
}
202+
203+
/* --------------------------------
204+
*pq_recvbuf - load some bytes into the input buffer
205+
*
206+
*returns 0 if OK, EOF if trouble
207+
* --------------------------------
208+
*/
209+
210+
int
211+
pq_recvbuf()
212+
{
213+
if (PqRecvPointer>0)
214+
{
215+
if (PqRecvLength>PqRecvPointer)
216+
{
217+
/* still some unread data, left-justify it in the buffer */
218+
memmove(PqRecvBuffer,PqRecvBuffer+PqRecvPointer,
219+
PqRecvLength-PqRecvPointer);
220+
PqRecvLength-=PqRecvPointer;
221+
PqRecvPointer=0;
222+
}
223+
else
224+
PqRecvLength=PqRecvPointer=0;
225+
}
226+
227+
/* Can fill buffer from PqRecvLength and upwards */
228+
for (;;)
229+
{
230+
intr=recv(MyProcPort->sock,PqRecvBuffer+PqRecvLength,
231+
PQ_BUFFER_SIZE-PqRecvLength,0);
232+
if (r <=0)
233+
{
234+
if (errno==EINTR)
235+
continue;/* Ok if interrupted */
236+
/* We would like to use elog() here, but dare not because elog
237+
* tries to write to the client, which will cause problems
238+
* if we have a hard communications failure ...
239+
* So just write the message to the postmaster log.
240+
*/
241+
fprintf(stderr,"pq_recvbuf: recv() failed, errno %d\n",errno);
242+
returnEOF;
243+
}
244+
/* r contains number of bytes read, so just incr length */
245+
PqRecvLength+=r;
246+
return0;
247+
}
165248
}
166249

167250
/* --------------------------------
@@ -194,7 +277,7 @@ pq_getstr(char *s, int maxlen)
194277
int
195278
pq_getnchar(char*s,intoff,intmaxlen)
196279
{
197-
intr=pqGetNBytes(s+off,maxlen);
280+
intr=pqGetNBytes(s+off,maxlen);
198281
s[off+maxlen]='\0';
199282
returnr;
200283
}
@@ -602,7 +685,7 @@ StreamConnection(int server_fd, Port *port)
602685
if (setsockopt(port->sock,pe->p_proto,TCP_NODELAY,
603686
&on,sizeof(on))<0)
604687
{
605-
elog(ERROR,"postmaster: setsockopt failed");
688+
elog(ERROR,"postmaster: setsockopt failed: %m");
606689
returnSTATUS_ERROR;
607690
}
608691
}
@@ -644,18 +727,9 @@ pq_putncharlen(char *s, int n)
644727
*/
645728
intpq_putchar(charc)
646729
{
647-
charisDone=0;
648-
649-
do {
650-
if (send(MyProcPort->sock,&c,1,0)!=1) {
651-
if (errno!=EINTR)
652-
returnEOF;/* Anything other than interrupt is error! */
653-
}
654-
else
655-
isDone=1;/* Done if we sent one char */
656-
}while (!isDone);
657-
returnc;
730+
if (PqSendPointer >=PQ_BUFFER_SIZE)
731+
if (pq_flush())/* If buffer is full, then flush it out */
732+
returnEOF;
733+
PqSendBuffer[PqSendPointer++]=c;/* Put in buffer */
734+
returnc;
658735
}
659-
660-
661-

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp