11// Package pool manages a user defined set of resources.
22// Based on the work by Fatih Arslan with his pool package.
3- // https://github.com/fatih/pool/tree/v2 .0.0
3+ // https://github.com/fatih/pool/tree/v1 .0.0
44package pool
55
66import (
2929 mutex sync.Mutex
3030 resources queue
3131 factory Factory
32+ closed bool
3233 }
3334)
3435
@@ -46,33 +47,12 @@ func New(factory Factory, capacity int) (*Pool, error) {
4647 }, nil
4748}
4849
49- // getQueue returns a safe copy of the resource queue.
50- func (p * Pool ) getQueue () queue {
51- var resources queue
52- p .mutex .Lock ()
53- {
54- resources = p .resources
55- }
56- p .mutex .Unlock ()
57-
58- return resources
59- }
60-
6150// Acquire retrieves a resource from the pool.
6251func (p * Pool ) Acquire () (Resource , error ) {
63- // Get a safe copy of the queue and check
64- // if the queue has been closed.
65- resources := p .getQueue ()
66- if resources == nil {
67- return nil , errors .New ("Pool has been closed." )
68- }
69-
70- // The queue is still open so acquire a resource.
71-
7252 select {
73- case resource := <- resources :
53+ case resource , ok := <- p . resources :
7454 fmt .Println ("Acquire:" , "Shared Resource" )
75- if resource == nil {
55+ if ! ok {
7656 return nil , errors .New ("Pool has been closed." )
7757 }
7858 return resource , nil
@@ -86,21 +66,21 @@ func (p *Pool) Acquire() (Resource, error) {
8666// Release places the resource back into the queue or closes
8767// the resource for good.
8868func (p * Pool ) Release (resource Resource ) {
69+ // Secure this operation with the Close operation.
8970 p .mutex .Lock ()
9071 defer p .mutex .Unlock ()
9172
92- // If the queue is closed, close the resource before returning.
93- if p .resources == nil {
73+ // If the pool is closed, close the resource before returning.
74+ if p .closed {
9475 resource .Close ()
9576 return
9677 }
9778
9879 // The queue is still open so release the resource.
9980
10081 select {
101- // Attempt to place the resource back into the queue first.
102- // If the queue is full, this will block and the default case
103- // will be executed.
82+ // Attempt to place the resource back into the queue first. If the queue
83+ // is full, then the default case will be executed.
10484 case p .resources <- resource :
10585 fmt .Println ("Release:" , "In Queue" )
10686
@@ -113,23 +93,18 @@ func (p *Pool) Release(resource Resource) {
11393
11494// Close will shutdown the pool and close all existing resources.
11595func (p * Pool ) Close () {
116- // Get a safe copy of the queue and set the queue to nil.
117- var resources queue
96+ // Secure this operation with the Release operation.
11897 p .mutex .Lock ()
119- {
120- resources = p .resources
121- p .resources = nil
122- }
123- p .mutex .Unlock ()
98+ defer p .mutex .Unlock ()
12499
125- // Is the queue already closed.
126- if resources == nil {
127- return
128- }
100+ // If the pool is not closed, the close it down.
101+ if ! p .closed {
102+ p .closed = true
129103
130- // Close the queue and close all existing resources.
131- close (resources )
132- for resource := range resources {
133- resource .Close ()
104+ // Close the queue and close all existing resources.
105+ close (p .resources )
106+ for resource := range p .resources {
107+ resource .Close ()
108+ }
134109 }
135110}
0 commit comments