| 89 | } |
| 90 | |
| 91 | func (p *VMPool) Get(ctx context.Context) (*VM, error) { |
| 92 | for { |
| 93 | p.mu.Lock() |
| 94 | if p.closed { |
| 95 | p.mu.Unlock() |
| 96 | return nil, ErrVMPoolClosed |
| 97 | } |
| 98 | if n := len(p.idle); n > 0 { |
| 99 | item := p.idle[n-1] |
| 100 | p.idle = p.idle[:n-1] |
| 101 | p.mu.Unlock() |
| 102 | return item.vm, nil |
| 103 | } |
| 104 | if p.total < p.config.MaxTotal { |
| 105 | p.total++ |
| 106 | p.mu.Unlock() |
| 107 | return p.base.Fork(), nil |
| 108 | } |
| 109 | changed := p.changed |
| 110 | p.mu.Unlock() |
| 111 | |
| 112 | select { |
| 113 | case <-ctx.Done(): |
| 114 | return nil, ctx.Err() |
| 115 | case <-changed: |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | func (p *VMPool) Return(_ context.Context, vm *VM) error { |
| 121 | if vm == nil { |