-
Notifications
You must be signed in to change notification settings - Fork 8
/
pool.go
103 lines (85 loc) · 2.12 KB
/
pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package monte
import (
"github.com/valyala/bytebufferpool"
"sync"
"time"
)
type Context struct {
conn *Conn
seq uint32
buf []byte
}
func (c *Context) Conn() *Conn { return c.conn }
func (c *Context) Body() []byte { return c.buf }
func (c *Context) Reply(buf []byte) error { return c.conn.send(c.seq, buf) }
var contextPool sync.Pool
func acquireContext(conn *Conn, seq uint32, buf []byte) *Context {
v := contextPool.Get()
if v == nil {
v = &Context{}
}
ctx := v.(*Context)
ctx.conn = conn
ctx.seq = seq
ctx.buf = buf
return ctx
}
func releaseContext(ctx *Context) { contextPool.Put(ctx) }
type pendingWrite struct {
buf *bytebufferpool.ByteBuffer // payload
wait bool // signal to caller if they're waiting
err error // keeps track of any socket errors on write
wg sync.WaitGroup // signals the caller that this write is complete
}
var pendingWritePool sync.Pool
func acquirePendingWrite(buf *bytebufferpool.ByteBuffer, wait bool) *pendingWrite {
v := pendingWritePool.Get()
if v == nil {
v = &pendingWrite{}
}
pw := v.(*pendingWrite)
pw.buf = buf
pw.wait = wait
return pw
}
func releasePendingWrite(pw *pendingWrite) { pw.err = nil; pendingWritePool.Put(pw) }
type pendingRequest struct {
dst []byte // dst to copy response to
err error // error while waiting for response
wg sync.WaitGroup // signals the caller that the response has been received
}
var pendingRequestPool sync.Pool
func acquirePendingRequest(dst []byte) *pendingRequest {
v := pendingRequestPool.Get()
if v == nil {
v = &pendingRequest{}
}
pr := v.(*pendingRequest)
pr.dst = dst
return pr
}
func releasePendingRequest(pr *pendingRequest) {
pr.dst = nil
pr.err = nil
pendingRequestPool.Put(pr)
}
var zeroTime time.Time
var timerPool sync.Pool
func AcquireTimer(timeout time.Duration) *time.Timer {
v := timerPool.Get()
if v == nil {
return time.NewTimer(timeout)
}
t := v.(*time.Timer)
t.Reset(timeout)
return t
}
func ReleaseTimer(t *time.Timer) {
if !t.Stop() {
select {
case <-t.C:
default:
}
}
timerPool.Put(t)
}