1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Pipe adapter to connect code expecting an io.Reader
6 // with code expecting an io.Writer.
15 // onceError is an object that will only store an error once.
16 type onceError
struct {
17 sync
.Mutex
// guards following
21 func (a
*onceError
) Store(err error
) {
29 func (a
*onceError
) Load() error
{
35 // ErrClosedPipe is the error used for read or write operations on a closed pipe.
36 var ErrClosedPipe
= errors
.New("io: read/write on closed pipe")
38 // A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
40 wrMu sync
.Mutex
// Serializes Write operations
44 once sync
.Once
// Protects closing done
50 func (p
*pipe
) read(b
[]byte) (n
int, err error
) {
53 return 0, p
.readCloseError()
63 return 0, p
.readCloseError()
67 func (p
*pipe
) closeRead(err error
) error
{
72 p
.once
.Do(func() { close(p
.done
) })
76 func (p
*pipe
) write(b
[]byte) (n
int, err error
) {
79 return 0, p
.writeCloseError()
85 for once
:= true; once ||
len(b
) > 0; once
= false {
92 return n
, p
.writeCloseError()
98 func (p
*pipe
) closeWrite(err error
) error
{
103 p
.once
.Do(func() { close(p
.done
) })
107 // readCloseError is considered internal to the pipe type.
108 func (p
*pipe
) readCloseError() error
{
109 rerr
:= p
.rerr
.Load()
110 if werr
:= p
.werr
.Load(); rerr
== nil && werr
!= nil {
116 // writeCloseError is considered internal to the pipe type.
117 func (p
*pipe
) writeCloseError() error
{
118 werr
:= p
.werr
.Load()
119 if rerr
:= p
.rerr
.Load(); werr
== nil && rerr
!= nil {
125 // A PipeReader is the read half of a pipe.
126 type PipeReader
struct {
130 // Read implements the standard Read interface:
131 // it reads data from the pipe, blocking until a writer
132 // arrives or the write end is closed.
133 // If the write end is closed with an error, that error is
134 // returned as err; otherwise err is EOF.
135 func (r
*PipeReader
) Read(data
[]byte) (n
int, err error
) {
136 return r
.p
.read(data
)
139 // Close closes the reader; subsequent writes to the
140 // write half of the pipe will return the error ErrClosedPipe.
141 func (r
*PipeReader
) Close() error
{
142 return r
.CloseWithError(nil)
145 // CloseWithError closes the reader; subsequent writes
146 // to the write half of the pipe will return the error err.
148 // CloseWithError never overwrites the previous error if it exists
149 // and always returns nil.
150 func (r
*PipeReader
) CloseWithError(err error
) error
{
151 return r
.p
.closeRead(err
)
154 // A PipeWriter is the write half of a pipe.
155 type PipeWriter
struct {
159 // Write implements the standard Write interface:
160 // it writes data to the pipe, blocking until one or more readers
161 // have consumed all the data or the read end is closed.
162 // If the read end is closed with an error, that err is
163 // returned as err; otherwise err is ErrClosedPipe.
164 func (w
*PipeWriter
) Write(data
[]byte) (n
int, err error
) {
165 return w
.p
.write(data
)
168 // Close closes the writer; subsequent reads from the
169 // read half of the pipe will return no bytes and EOF.
170 func (w
*PipeWriter
) Close() error
{
171 return w
.CloseWithError(nil)
174 // CloseWithError closes the writer; subsequent reads from the
175 // read half of the pipe will return no bytes and the error err,
176 // or EOF if err is nil.
178 // CloseWithError never overwrites the previous error if it exists
179 // and always returns nil.
180 func (w
*PipeWriter
) CloseWithError(err error
) error
{
181 return w
.p
.closeWrite(err
)
184 // Pipe creates a synchronous in-memory pipe.
185 // It can be used to connect code expecting an io.Reader
186 // with code expecting an io.Writer.
188 // Reads and Writes on the pipe are matched one to one
189 // except when multiple Reads are needed to consume a single Write.
190 // That is, each Write to the PipeWriter blocks until it has satisfied
191 // one or more Reads from the PipeReader that fully consume
193 // The data is copied directly from the Write to the corresponding
194 // Read (or Reads); there is no internal buffering.
196 // It is safe to call Read and Write in parallel with each other or with Close.
197 // Parallel calls to Read and parallel calls to Write are also safe:
198 // the individual calls will be gated sequentially.
199 func Pipe() (*PipeReader
, *PipeWriter
) {
201 wrCh
: make(chan []byte),
202 rdCh
: make(chan int),
203 done
: make(chan struct{}),
205 return &PipeReader
{p
}, &PipeWriter
{p
}