sync: new_mutex() and new_waitgroup()

pull/2552/head
Delyan Angelov 2019-10-25 17:24:40 +03:00 committed by Alexander Medvednikov
parent e04c4ad852
commit 32b3611026
4 changed files with 41 additions and 9 deletions

View File

@ -17,7 +17,7 @@ struct Story {
struct Fetcher {
mut:
mu sync.Mutex
mu &sync.Mutex
ids []int
cursor int
wg &sync.WaitGroup
@ -65,12 +65,15 @@ fn main() {
ids = tmp
}
mut wg := &sync.WaitGroup{}
fetcher := &Fetcher{ids: ids, wg: wg} // wg sent via ptr
wg.add(ids.len)
wg := sync.new_waitgroup()
mtx := sync.new_mutex()
mut fetcher := &Fetcher{ids: ids}
fetcher.mu = &mtx
fetcher.wg = &wg
fetcher.wg.add(ids.len)
for i := 0; i < NR_THREADS; i++ {
go fetcher.fetch()
}
wg.wait()
fetcher.wg.wait()
}

View File

@ -5,10 +5,18 @@
module sync
#include <pthread.h>
//[init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function.
pub struct Mutex {
mutex C.pthread_mutex_t
}
pub fn new_mutex() Mutex {
m := Mutex{}
C.pthread_mutex_init( &m.mutex, C.NULL)
return m
}
pub fn (m mut Mutex) lock() {
C.pthread_mutex_lock(&m.mutex)
}

View File

@ -7,6 +7,7 @@ module sync
// Mutex HANDLE
type MHANDLE voidptr
//[init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function.
pub struct Mutex {
mut:
mx MHANDLE // mutex handle
@ -38,6 +39,19 @@ const (
WAIT_FAILED = 0xFFFFFFFF
)
pub fn new_mutex() Mutex {
sm := Mutex{}
unsafe {
mut m := sm
m.mx = C.CreateMutex(0, false, 0)
if isnil(m.mx) {
m.state = .broken // handle broken and mutex state are broken
return sm
}
return sm
}
}
pub fn (m mut Mutex) lock() {
// if mutex handle not initalized
if isnil(m.mx) {
@ -49,9 +63,9 @@ pub fn (m mut Mutex) lock() {
}
state := C.WaitForSingleObject(m.mx, INFINITE) // infinite wait
m.state = match state {
WAIT_ABANDONED => { MutexState.abandoned }
WAIT_OBJECT_0 => { MutexState.waiting }
else => { MutexState.broken }
WAIT_ABANDONED { MutexState.abandoned }
WAIT_OBJECT_0 { MutexState.waiting }
else { MutexState.broken }
}
}

View File

@ -4,12 +4,19 @@
module sync
//[init_with=new_waitgroup] // TODO: implement support for init_with struct attribute, and disallow WaitGroup{} from outside the sync.new_waitgroup() function.
pub struct WaitGroup {
mut:
mu Mutex
active int
}
pub fn new_waitgroup() WaitGroup {
mut w := WaitGroup{}
w.mu = sync.new_mutex()
return w
}
pub fn (wg mut WaitGroup) add(delta int) {
wg.mu.lock()
wg.active += delta