From 32b3611026896863d75801c9ded79685e6dd00ee Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 25 Oct 2019 17:24:40 +0300 Subject: [PATCH] sync: new_mutex() and new_waitgroup() --- examples/news_fetcher.v | 15 +++++++++------ vlib/sync/sync_nix.v | 8 ++++++++ vlib/sync/{sync_win.v => sync_windows.v} | 20 +++++++++++++++++--- vlib/sync/waitgroup.v | 7 +++++++ 4 files changed, 41 insertions(+), 9 deletions(-) rename vlib/sync/{sync_win.v => sync_windows.v} (76%) diff --git a/examples/news_fetcher.v b/examples/news_fetcher.v index 4dd16fa967..dce80a2487 100644 --- a/examples/news_fetcher.v +++ b/examples/news_fetcher.v @@ -17,10 +17,10 @@ struct Story { struct Fetcher { mut: - mu sync.Mutex + mu &sync.Mutex ids []int cursor int - wg &sync.WaitGroup + wg &sync.WaitGroup } fn (f mut Fetcher) fetch() { @@ -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() } diff --git a/vlib/sync/sync_nix.v b/vlib/sync/sync_nix.v index 46707bd8b0..2287a81d6d 100644 --- a/vlib/sync/sync_nix.v +++ b/vlib/sync/sync_nix.v @@ -5,10 +5,18 @@ module sync #include + +//[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) } diff --git a/vlib/sync/sync_win.v b/vlib/sync/sync_windows.v similarity index 76% rename from vlib/sync/sync_win.v rename to vlib/sync/sync_windows.v index be540803eb..a2fdef37b0 100644 --- a/vlib/sync/sync_win.v +++ b/vlib/sync/sync_windows.v @@ -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 } } } diff --git a/vlib/sync/waitgroup.v b/vlib/sync/waitgroup.v index 669401e4e7..307192e824 100644 --- a/vlib/sync/waitgroup.v +++ b/vlib/sync/waitgroup.v @@ -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