sync/waitgroup: use value mutex and semaphore; remove sync.Waiter (#8431)

pull/8422/head^2
Uwe Krüger 2021-01-30 10:08:43 +01:00 committed by GitHub
parent 391d62bca5
commit 6477748e88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 8 additions and 65 deletions

View File

@ -1,22 +0,0 @@
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module sync
[ref_only]
struct Waiter{
mut:
mx &Mutex
}
pub fn (mut w Waiter) wait() {
w.mx.m_lock()
}
pub fn (mut w Waiter) stop() {
w.mx.unlock()
}
pub fn new_waiter() &Waiter {
w := &Waiter{mx: new_mutex()}
return w
}

View File

@ -1,35 +0,0 @@
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module sync
// We cannot simply use Mutex.lock() in the waitgroup.wait() method
// as it will not block since it's used in the same thread.
// docs:
// Any thread with a handle to a mutex object can use one of the
// wait functions to request ownership of the mutex object.
// If the mutex object is owned by another thread, the wait
// function blocks the requesting thread until the owning thread
// releases the mutex object using the ReleaseMutex function.
// Source:
// https://docs.microsoft.com/en-us/windows/win32/sync/mutex-objects
[ref_only]
struct Waiter{
mut:
event MHANDLE
}
pub fn (mut w Waiter) wait() {
C.WaitForSingleObject(w.event, C.INFINITE) // infinite wait
}
pub fn (mut w Waiter) stop() {
C.SetEvent(w.event)
}
pub fn new_waiter() &Waiter {
unsafe {
sm := &Waiter{event: MHANDLE(C.CreateEvent(0, false, true, 0))}
return sm
}
}

View File

@ -14,15 +14,15 @@ module sync
struct WaitGroup {
mut:
task_count int // current task count
task_count_mutex &Mutex // This mutex protects the task_count count in add()
wait_blocker &Waiter = &Waiter(0) // This blocks the wait() until released by add()
task_count_mutex Mutex // This mutex protects the task_count count in add()
wait_blocker Semaphore // This blocks the wait() until released by add()
}
pub fn new_waitgroup() &WaitGroup {
return &WaitGroup{
task_count_mutex: new_mutex()
wait_blocker: new_waiter()
}
mut wg := &WaitGroup{}
wg.task_count_mutex.init()
wg.wait_blocker.init(1)
return wg
}
// add increments (+ve delta) or decrements (-ve delta) task count by delta
@ -43,7 +43,7 @@ pub fn (mut wg WaitGroup) add(delta int) {
panic('Negative number of jobs in waitgroup')
}
if wg.task_count == 0 { // if no more task_count tasks
wg.wait_blocker.stop() // unblock wait()
wg.wait_blocker.post() // unblock wait()
}
}
@ -55,5 +55,5 @@ pub fn (mut wg WaitGroup) done() {
// wait blocks until all tasks are done (task count becomes zero)
pub fn (mut wg WaitGroup) wait() {
wg.wait_blocker.wait() // blocks until task_count becomes 0
wg.wait_blocker.stop() // allow other wait()s to unblock or reuse wait group
wg.wait_blocker.post() // allow other wait()s to unblock or reuse wait group
}