func (w *PipeWriter) Write(data []byte) (int, error) {
	w.cond.L.Lock()
	defer w.cond.L.Unlock()
	if w.werr != nil {
		return 0, w.werr
	}
	n, err := w.buf.Write(data)
	w.cond.Signal()
	return n, err
}
Write implements the standard Write interface: it writes data to the internal
buffer. If the read end is closed with an error, that err is returned as err;
otherwise err is ErrClosedPipe.
package bufpipe
import (
	"bytes"
	"errors"
	"io"
	"sync"
)
var ErrClosedPipe = errors.New("bufpipe: read/write on closed pipe")
type pipe struct {
	cond       *sync.Cond
	buf        *bytes.Buffer
	rerr, werr error
}
type PipeReader struct {
	*pipe
}
type PipeWriter struct {
	*pipe
}
func New(buf []byte) (*PipeReader, *PipeWriter) {
	p := &pipe{
		buf:  bytes.NewBuffer(buf),
		cond: sync.NewCond(new(sync.Mutex)),
	}
	return &PipeReader{
			pipe: p,
		}, &PipeWriter{
			pipe: p,
		}
}
func (r *PipeReader) Read(data []byte) (int, error) {
	r.cond.L.Lock()
	defer r.cond.L.Unlock()
RETRY:
	n, err := r.buf.Read(data)
	if err == io.EOF && r.rerr == nil && n == 0 {
		r.cond.Wait()
		goto RETRY
	}
	if err == io.EOF {
		return n, r.rerr
	}
	return n, err
}
func (r *PipeReader) Close() error {
	return r.CloseWithError(nil)
}
func (r *PipeReader) CloseWithError(err error) error {
	r.cond.L.Lock()
	defer r.cond.L.Unlock()
	if err == nil {
		err = ErrClosedPipe
	}
	r.werr = err
	return nil
}