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 {
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue