1 // Copyright 2010 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.
11 // A Pipeline manages a pipelined in-order request/response sequence.
13 // To use a Pipeline p to manage multiple clients on a connection,
14 // each client should run:
16 // id := p.Next() // take a number
18 // p.StartRequest(id) // wait for turn to send request
20 // p.EndRequest(id) // notify Pipeline that request is sent
22 // p.StartResponse(id) // wait for turn to read response
24 // p.EndResponse(id) // notify Pipeline that response is read
26 // A pipelined server can use the same calls to ensure that
27 // responses computed in parallel are written in the correct order.
28 type Pipeline
struct {
35 // Next returns the next id for a request/response pair.
36 func (p
*Pipeline
) Next() uint {
44 // StartRequest blocks until it is time to send (or, if this is a server, receive)
45 // the request with the given id.
46 func (p
*Pipeline
) StartRequest(id
uint) {
50 // EndRequest notifies p that the request with the given id has been sent
51 // (or, if this is a server, received).
52 func (p
*Pipeline
) EndRequest(id
uint) {
56 // StartResponse blocks until it is time to receive (or, if this is a server, send)
57 // the request with the given id.
58 func (p
*Pipeline
) StartResponse(id
uint) {
62 // EndResponse notifies p that the response with the given id has been received
63 // (or, if this is a server, sent).
64 func (p
*Pipeline
) EndResponse(id
uint) {
68 // A sequencer schedules a sequence of numbered events that must
69 // happen in order, one after the other. The event numbering must start
70 // at 0 and increment without skipping. The event number wraps around
71 // safely as long as there are not 2^32 simultaneous events pending.
72 type sequencer
struct {
75 wait
map[uint]chan uint
78 // Start waits until it is time for the event numbered id to begin.
79 // That is, except for the first event, it waits until End(id-1) has
81 func (s
*sequencer
) Start(id
uint) {
89 s
.wait
= make(map[uint]chan uint)
96 // End notifies the sequencer that the event numbered id has completed,
97 // allowing it to schedule the event numbered id+1. It is a run-time error
98 // to call End with an id that is not the number of the active event.
99 func (s
*sequencer
) End(id
uint) {
107 s
.wait
= make(map[uint]chan uint)
111 s
.wait
[id
] = nil, false