I had the idea of adding a sync.WaitGroup
Limit(max int)
function to resrict the number of the WaitGroup
counter.
So I opened the waitgroup.go
file in go/src/sync
and made the changes, saved the file and tried testing it in a main.go file on my desktop. When I ran the file, it says:
$ go run main.go
wg.Limit undefined (type sync.WaitGroup has no field or method Limit)
To fix this error message, I copied the folder from go/src/sync
into the folder on my desktop containing my main.go
file and changed the import from sync
to ./sync
.
After running go run main.go
this time, I got the following output:
$ go run main.go
sync\mutex.go:14:2: use of internal package not allowed
sync\pool.go:8:2: use of internal package not allowed
syncwmutex.go:8:2: use of internal package not allowed
sync\waitgroup.go:8:2: use of internal package not allowed
To fix these messages, I copied go/src/internal
into the folder on my desktop containing my main.go
file and I modified all the files in ./sync
that reference internal/..
to ./internal/..
I run it again and I get the following output:
$ go run main.go
# _/C_/.../sync
sync\mutex.go:20: missing function body for "throw"
sync\pool.go:66: missing function body for "fastrand"
sync\pool.go:249: missing function body for "runtime_registerPoolCleanup"
sync\pool.go:250: missing function body for "runtime_procPin"
sync\pool.go:251: missing function body for "runtime_procUnpin"
syncuntime.go:14: missing function body for "runtime_Semacquire"
syncuntime.go:17: missing function body for "runtime_SemacquireMutex"
syncuntime.go:23: missing function body for "runtime_Semrelease"
syncuntime.go:36: missing function body for "runtime_notifyListAdd"
syncuntime.go:39: missing function body for "runtime_notifyListWait"
syncuntime.go:39: too many errors
How can I implement my simple idea by modifying the source files of go/src
without receiving these errors?
In your installation of Go, navigate to the src
folder and run the file called run.bat
which will recompile all the packages removing the first error you described.
I really wouldn't do this by changing the standard library, but instead wrap the WaitGroup to keep track of the counter like so:
type wg_limit struct {
wg sync.WaitGroup
current, max int
}
func (wgl *wg_limit) Add(delta int) error {
if wgl.current+delta > wgl.max {
return fmt.Errorf("counter exceeded (current: %d, max: %d)", wgl.current, wgl.max)
}
wgl.current += delta
wgl.wg.Add(delta)
return nil
}
func (wgl *wg_limit) Done() {
wgl.current -= 1
wgl.wg.Done()
}
Then init wg_limit with a value for max and use the resulting variable just like a WaitGroup:
wgl := wg_limit{max: 3}
if err := wgl.Add(1); err != nil {
// go something()
// ...
wgl.Done()
}
If the WaitGroup counter would be exceeded by the delta of Add(delta), an error is returned and the WaitGroup is unchanged.