-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpool.go
More file actions
50 lines (42 loc) · 1.28 KB
/
pool.go
File metadata and controls
50 lines (42 loc) · 1.28 KB
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
package purejson
import "sync"
// ParserPool reuses Parser instances across goroutines while preserving the
// one-live-doc-per-parser invariant. There is no Close method: sync.Pool
// cannot be drained deterministically. Parsers left in the pool when it is
// discarded are reclaimed by the GC finalizer; the same leak-warning rules
// that apply to standalone parsers apply here.
type ParserPool struct {
pool sync.Pool
}
// NewParserPool constructs an empty parser pool.
func NewParserPool() *ParserPool {
return &ParserPool{}
}
// Get returns a reusable parser or allocates a new one on a pool miss.
func (p *ParserPool) Get() (*Parser, error) {
if value := p.pool.Get(); value != nil {
if parser, ok := value.(*Parser); ok {
return parser, nil
}
}
return NewParser()
}
// Put returns a parser to the pool and rejects nil, closed, or still-busy
// parsers instead of silently repairing misuse. The parser's mutex is held
// across the pool insert so a racing Close cannot stash a just-closed parser.
func (p *ParserPool) Put(parser *Parser) error {
if parser == nil {
return ErrInvalidHandle
}
parser.mu.Lock()
defer parser.mu.Unlock()
switch {
case parser.closed:
return ErrClosed
case parser.liveDoc != 0:
return ErrParserBusy
default:
p.pool.Put(parser)
return nil
}
}