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 // ErrClosedPipe is the error used for read or write operations on a closed pipe.
16 var ErrClosedPipe
= errors
.New("io: read/write on closed pipe")
18 // A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
20 rl sync
.Mutex
// gates readers one at a time
21 wl sync
.Mutex
// gates writers one at a time
22 l sync
.Mutex
// protects remaining fields
23 data
[]byte // data remaining in pending write
24 rwait sync
.Cond
// waiting reader
25 wwait sync
.Cond
// waiting writer
26 rerr error
// if reader closed, error to give writes
27 werr error
// if writer closed, error to give reads
30 func (p
*pipe
) read(b
[]byte) (n
int, err error
) {
31 // One reader at a time.
39 return 0, ErrClosedPipe
60 func (p
*pipe
) write(b
[]byte) (n
int, err error
) {
61 // pipe uses nil to mean not available
66 // One writer at a time.
92 n
= len(b
) - len(p
.data
)
93 p
.data
= nil // in case of rerr or werr
97 func (p
*pipe
) rclose(err error
) {
108 func (p
*pipe
) wclose(err error
) {
119 // A PipeReader is the read half of a pipe.
120 type PipeReader
struct {
124 // Read implements the standard Read interface:
125 // it reads data from the pipe, blocking until a writer
126 // arrives or the write end is closed.
127 // If the write end is closed with an error, that error is
128 // returned as err; otherwise err is EOF.
129 func (r
*PipeReader
) Read(data
[]byte) (n
int, err error
) {
130 return r
.p
.read(data
)
133 // Close closes the reader; subsequent writes to the
134 // write half of the pipe will return the error ErrClosedPipe.
135 func (r
*PipeReader
) Close() error
{
136 return r
.CloseWithError(nil)
139 // CloseWithError closes the reader; subsequent writes
140 // to the write half of the pipe will return the error err.
141 func (r
*PipeReader
) CloseWithError(err error
) error
{
146 // A PipeWriter is the write half of a pipe.
147 type PipeWriter
struct {
151 // Write implements the standard Write interface:
152 // it writes data to the pipe, blocking until one or more readers
153 // have consumed all the data or the read end is closed.
154 // If the read end is closed with an error, that err is
155 // returned as err; otherwise err is ErrClosedPipe.
156 func (w
*PipeWriter
) Write(data
[]byte) (n
int, err error
) {
157 return w
.p
.write(data
)
160 // Close closes the writer; subsequent reads from the
161 // read half of the pipe will return no bytes and EOF.
162 func (w
*PipeWriter
) Close() error
{
163 return w
.CloseWithError(nil)
166 // CloseWithError closes the writer; subsequent reads from the
167 // read half of the pipe will return no bytes and the error err,
168 // or EOF if err is nil.
170 // CloseWithError always returns nil.
171 func (w
*PipeWriter
) CloseWithError(err error
) error
{
176 // Pipe creates a synchronous in-memory pipe.
177 // It can be used to connect code expecting an io.Reader
178 // with code expecting an io.Writer.
180 // Reads and Writes on the pipe are matched one to one
181 // except when multiple Reads are needed to consume a single Write.
182 // That is, each Write to the PipeWriter blocks until it has satisfied
183 // one or more Reads from the PipeReader that fully consume
185 // The data is copied directly from the Write to the corresponding
186 // Read (or Reads); there is no internal buffering.
188 // It is safe to call Read and Write in parallel with each other or with Close.
189 // Parallel calls to Read and parallel calls to Write are also safe:
190 // the individual calls will be gated sequentially.
191 func Pipe() (*PipeReader
, *PipeWriter
) {