fix: deadlock in pool

This commit is contained in:
Paul Pan 2024-01-06 21:03:30 +08:00
parent 7f71fb4554
commit b5d14d5a4b
Signed by: Paul
GPG Key ID: D639BDF5BA578AF4
4 changed files with 50 additions and 5 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/woj /woj
/config.yaml /config.yaml
/dsn.txt /dsn.txt
/coverage.*

View File

@ -14,7 +14,7 @@ LDFLAGS += -s -w
GOBUILD := $(GO) build -ldflags '$(LDFLAGS)' GOBUILD := $(GO) build -ldflags '$(LDFLAGS)'
GOBIN := $(shell go env GOPATH)/bin GOBIN := $(shell go env GOPATH)/bin
.PHONY: all build clean dep swagger fmt .PHONY: all build clean dep swagger fmt coverage test
default: all default: all
@ -35,3 +35,10 @@ swagger:
fmt: fmt:
go fmt ./... go fmt ./...
coverage:
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out -o coverage.html
test:
go test -race ./...

View File

@ -33,17 +33,18 @@ func (tp *TaskPool) Start() {
func (tp *TaskPool) AddTask(f func()) int { func (tp *TaskPool) AddTask(f func()) int {
tp.lck.Lock() tp.lck.Lock()
defer tp.lck.Unlock()
id := tp.curTaskID id := tp.curTaskID
tp.curTaskID++ tp.curTaskID++
task := Task{id: id, f: f}
tp.queue <- task
waitChan := make(chan struct{}) waitChan := make(chan struct{})
tp.waitMap[id] = waitChan tp.waitMap[id] = waitChan
tp.lck.Unlock()
task := Task{id: id, f: f}
tp.queue <- task
return id return id
} }

View File

@ -60,3 +60,39 @@ func TestTaskPool_WaitForTask(t *testing.T) {
pool.Stop() pool.Stop()
} }
func TestTaskPool_One(t *testing.T) {
pool := NewTaskPool(1, 1)
pool.Start()
lck := sync.Mutex{}
counter := 0
ids := make([]int, 0)
for i := 1; i <= 10; i++ {
f := func(i int) func() {
return func() {
lck.Lock()
t.Log("task", i, "locked")
counter += i
t.Log("task", i, "unlocked")
lck.Unlock()
time.Sleep(time.Duration(i*10) * time.Millisecond)
t.Log("task", i, "finished")
}
}(i)
id := pool.AddTask(f)
ids = append(ids, id)
}
for _, id := range ids {
pool.WaitForTask(id)
}
if counter != 55 {
t.Error("some tasks were not executed")
}
pool.Stop()
}