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
|
package smb2
import (
"context"
"sync"
)
type account struct {
m sync.Mutex
balance chan struct{}
_opening uint16
}
func openAccount(maxCreditBalance uint16) *account {
balance := make(chan struct{}, maxCreditBalance)
balance <- struct{}{} // initial balance
return &account{
balance: balance,
}
}
func (a *account) initRequest() uint16 {
return uint16(cap(a.balance) - len(a.balance))
}
func (a *account) loan(creditCharge uint16, ctx context.Context) (uint16, bool, error) {
select {
case <-a.balance:
case <-ctx.Done():
return 0, false, ctx.Err()
}
for i := uint16(1); i < creditCharge; i++ {
select {
case <-a.balance:
default:
return i, false, nil
}
}
return creditCharge, true, nil
}
func (a *account) opening() uint16 {
a.m.Lock()
ret := a._opening
a._opening = 0
a.m.Unlock()
return ret
}
func (a *account) charge(granted, requested uint16) {
if granted == 0 && requested == 0 {
return
}
a.m.Lock()
if granted < requested {
a._opening += requested - granted
}
a.m.Unlock()
for i := uint16(0); i < granted; i++ {
select {
case a.balance <- struct{}{}:
default:
return
}
}
}
|