sync/waitgroup: use value mutex and semaphore; remove sync.Waiter (#8431)
parent
391d62bca5
commit
6477748e88
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,15 +14,15 @@ module sync
|
||||||
struct WaitGroup {
|
struct WaitGroup {
|
||||||
mut:
|
mut:
|
||||||
task_count int // current task count
|
task_count int // current task count
|
||||||
task_count_mutex &Mutex // This mutex protects the task_count count in add()
|
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()
|
wait_blocker Semaphore // This blocks the wait() until released by add()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_waitgroup() &WaitGroup {
|
pub fn new_waitgroup() &WaitGroup {
|
||||||
return &WaitGroup{
|
mut wg := &WaitGroup{}
|
||||||
task_count_mutex: new_mutex()
|
wg.task_count_mutex.init()
|
||||||
wait_blocker: new_waiter()
|
wg.wait_blocker.init(1)
|
||||||
}
|
return wg
|
||||||
}
|
}
|
||||||
|
|
||||||
// add increments (+ve delta) or decrements (-ve delta) task count by delta
|
// 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')
|
panic('Negative number of jobs in waitgroup')
|
||||||
}
|
}
|
||||||
if wg.task_count == 0 { // if no more task_count tasks
|
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)
|
// wait blocks until all tasks are done (task count becomes zero)
|
||||||
pub fn (mut wg WaitGroup) wait() {
|
pub fn (mut wg WaitGroup) wait() {
|
||||||
wg.wait_blocker.wait() // blocks until task_count becomes 0
|
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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue