From 8578b8812a000304fa04c4f3bd35dff94cd08219 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Mon, 21 Jan 2013 09:24:46 +0200 Subject: [PATCH] Use system mutex/condition types instead of platform ones --- include/core/framebuffer.hpp | 2 +- include/core/window.hpp | 71 +--------------- include/library/threadtypes.hpp | 10 +++ include/lua/bitmap.hpp | 3 +- src/core/framebuffer.cpp | 10 +-- src/core/threaddebug.cpp | 24 +++--- src/core/window.cpp | 108 ++++++++--------------- src/dummy/thread.cpp | 60 ------------- src/lua/gui-bitmap.cpp | 11 ++- src/platform/wxwidgets/main.cpp | 23 +++-- src/platform/wxwidgets/messages.cpp | 14 +-- src/platform/wxwidgets/thread.cpp | 127 ---------------------------- 12 files changed, 87 insertions(+), 376 deletions(-) diff --git a/include/core/framebuffer.hpp b/include/core/framebuffer.hpp index a557119d..e1284eeb 100644 --- a/include/core/framebuffer.hpp +++ b/include/core/framebuffer.hpp @@ -43,7 +43,7 @@ public: private: triplebuffer_logic(triplebuffer_logic&); triplebuffer_logic& operator=(triplebuffer_logic&); - mutex* mut; + mutex_class mut; unsigned read_active; unsigned write_active; unsigned read_active_slot; diff --git a/include/core/window.hpp b/include/core/window.hpp index fe3b2854..620739b2 100644 --- a/include/core/window.hpp +++ b/include/core/window.hpp @@ -12,75 +12,6 @@ class emulator_status; -/** - * Mutex. - */ -struct mutex -{ -/** - * Hold mutex RAII-style. - */ - struct holder - { - holder(mutex& m) throw(); - ~holder() throw(); - private: - mutex& mut; - }; -/** - * Create a mutex. The returned mutex can be deleted using delete. - */ - static mutex& aquire() throw(std::bad_alloc); -/** - * Create a recursive mutex. The returned mutex can be deleted using delete. - */ - static mutex& aquire_rec() throw(std::bad_alloc); -/** - * Destroy a mutex. - */ - virtual ~mutex() throw(); -/** - * Lock a mutex. - */ - virtual void lock() throw() = 0; -/** - * Lock a mutex. - */ - virtual void unlock() throw() = 0; -protected: - mutex() throw(); -}; - -/** - * Condition variable. - */ -struct condition -{ -/** - * Create a condition variable. The returned condition can be freed using delete. - */ - static condition& aquire(mutex& m) throw(std::bad_alloc); -/** - * Destroy a condition. - */ - virtual ~condition() throw(); -/** - * Return associated mutex. - */ - mutex& associated() throw(); -/** - * Wait for condition. The associate mutex must be locked. - */ - virtual bool wait(uint64_t max_usec) throw() = 0; -/** - * Signal a condition. The associated mutex should be locked. - */ - virtual void signal() throw() = 0; -protected: - condition(mutex& m); - mutex& assoc; -}; - /** * Thread ID. */ @@ -305,7 +236,7 @@ struct platform /** * Get message buffer lock. */ - static mutex& msgbuf_lock() throw(); + static mutex_class& msgbuf_lock() throw(); /** * Set palette used on screen. */ diff --git a/include/library/threadtypes.hpp b/include/library/threadtypes.hpp index 3ff572e9..e958c713 100644 --- a/include/library/threadtypes.hpp +++ b/include/library/threadtypes.hpp @@ -11,6 +11,11 @@ typedef std::thread thread_class; typedef std::condition_variable cv_class; typedef std::mutex mutex_class; typedef std::unique_lock umutex_class; +typedef std::chrono::microseconds microsec_class; +inline void cv_timed_wait(cv_class& c, umutex_class& m, const microsec_class& t) +{ + c.wait_for(m, t); +} #else #include #include @@ -18,6 +23,11 @@ typedef boost::thread thread_class; typedef boost::condition_variable cv_class; typedef boost::mutex mutex_class; typedef boost::unique_lock umutex_class; +typedef boost::posix_time::microseconds microsec_class; +inline void cv_timed_wait(cv_class& c, umutex_class& m, const microsec_class& t) +{ + c.timed_wait(m, t); +} #endif #endif diff --git a/include/lua/bitmap.hpp b/include/lua/bitmap.hpp index 5e0ad635..83b18482 100644 --- a/include/lua/bitmap.hpp +++ b/include/lua/bitmap.hpp @@ -6,6 +6,7 @@ #include #include "core/window.hpp" #include "library/framebuffer.hpp" +#include "library/threadtypes.hpp" struct lua_bitmap { @@ -28,7 +29,7 @@ struct lua_palette std::vector colors; lua_palette(); ~lua_palette(); - mutex* palette_mutex; + mutex_class palette_mutex; }; struct lua_loaded_bitmap diff --git a/src/core/framebuffer.cpp b/src/core/framebuffer.cpp index dc62ae9f..324f02bd 100644 --- a/src/core/framebuffer.cpp +++ b/src/core/framebuffer.cpp @@ -258,7 +258,6 @@ framebuffer_raw get_framebuffer() throw(std::bad_alloc) triplebuffer_logic::triplebuffer_logic() throw(std::bad_alloc) { - mut = &mutex::aquire(); last_complete_slot = 0; read_active = false; write_active = false; @@ -268,12 +267,11 @@ triplebuffer_logic::triplebuffer_logic() throw(std::bad_alloc) triplebuffer_logic::~triplebuffer_logic() throw() { - delete mut; } unsigned triplebuffer_logic::start_write() throw() { - mutex::holder h(*mut); + umutex_class h(mut); if(!write_active) { //We need to avoid hitting last complete slot or slot that is active for read. if(last_complete_slot != 0 && read_active_slot != 0) @@ -289,14 +287,14 @@ unsigned triplebuffer_logic::start_write() throw() void triplebuffer_logic::end_write() throw() { - mutex::holder h(*mut); + umutex_class h(mut); if(!--write_active) last_complete_slot = write_active_slot; } unsigned triplebuffer_logic::start_read() throw() { - mutex::holder h(*mut); + umutex_class h(mut); if(!read_active) read_active_slot = last_complete_slot; read_active++; @@ -305,6 +303,6 @@ unsigned triplebuffer_logic::start_read() throw() void triplebuffer_logic::end_read() throw() { - mutex::holder h(*mut); + umutex_class h(mut); read_active--; } diff --git a/src/core/threaddebug.cpp b/src/core/threaddebug.cpp index 015c4340..8efc0a0f 100644 --- a/src/core/threaddebug.cpp +++ b/src/core/threaddebug.cpp @@ -1,5 +1,6 @@ #include "core/threaddebug.hpp" #include "core/window.hpp" +#include "library/threadtypes.hpp" #define DESIGNATED_THREADS 16 @@ -7,7 +8,8 @@ namespace { volatile thread_id* threads[DESIGNATED_THREADS]; volatile bool thread_marked; - mutex* malloc_mutex; + mutex_class malloc_mutex; + bool initialized = false; } void assert_thread(signed shouldbe, const std::string& desc) @@ -40,8 +42,8 @@ void mark_thread_as(signed call_me) #ifdef MAKE_MALLOC_THREADSAFE void init_threaded_malloc() { - if(!malloc_mutex) - malloc_mutex = &mutex::aquire(); + if(!initialized) + initialized = true; } extern "C" @@ -54,33 +56,33 @@ void __real_free(void*); void* __wrap_malloc(size_t block) { - if(!malloc_mutex) + if(!initialized) return __real_malloc(block); - mutex::holder(*malloc_mutex); + umutex_class h(malloc_mutex); return __real_malloc(block); } void* __wrap_calloc(size_t count, size_t size) { - if(!malloc_mutex) + if(!initialized) return __real_calloc(count, size); - mutex::holder(*malloc_mutex); + umutex_class h(malloc_mutex); return __real_calloc(count, size); } void* __wrap_realloc(void* block, size_t size) { - if(!malloc_mutex) + if(!initialized) return __real_realloc(block, size); - mutex::holder(*malloc_mutex); + umutex_class h(malloc_mutex); return __real_realloc(block, size); } void __wrap_free(void* block) { - if(!malloc_mutex) + if(!initialized) return __real_free(block); - mutex::holder(*malloc_mutex); + umutex_class h(malloc_mutex); return __real_free(block); } } diff --git a/src/core/window.cpp b/src/core/window.cpp index 72da66e1..97c86687 100644 --- a/src/core/window.cpp +++ b/src/core/window.cpp @@ -9,6 +9,7 @@ #include "library/framebuffer.hpp" #include "library/string.hpp" #include "library/minmax.hpp" +#include "library/threadtypes.hpp" #include #include @@ -28,39 +29,6 @@ #define MAXMESSAGES 5000 #define INIT_WIN_SIZE 6 -mutex::holder::holder(mutex& m) throw() - : mut(m) -{ - mut.lock(); -} - -mutex::holder::~holder() throw() -{ - mut.unlock(); -} - -mutex::~mutex() throw() -{ -} - -mutex::mutex() throw() -{ -} - -condition::~condition() throw() -{ -} - -mutex& condition::associated() throw() -{ - return assoc; -} - -condition::condition(mutex& m) - : assoc(m) -{ -} - thread_id::thread_id() throw() { } @@ -347,7 +315,7 @@ messagebuffer platform::msgbuf(MAXMESSAGES, INIT_WIN_SIZE); void platform::message(const std::string& msg) throw(std::bad_alloc) { - mutex::holder h(msgbuf_lock()); + umutex_class h(msgbuf_lock()); std::string msg2 = msg; while(msg2 != "") { std::string forlog; @@ -374,8 +342,8 @@ void platform::fatal_error() throw() namespace { - mutex* queue_lock; - condition* queue_condition; + mutex_class queue_lock; + cv_class queue_condition; std::deque keypresses; std::deque commands; std::deque> functions; @@ -387,50 +355,46 @@ namespace void init_threading() { - if(!queue_lock) - queue_lock = &mutex::aquire(); - if(!queue_condition) - queue_condition = &condition::aquire(*queue_lock); } void internal_run_queues(bool unlocked) throw() { init_threading(); if(!unlocked) - queue_lock->lock(); + queue_lock.lock(); try { //Flush keypresses. while(!keypresses.empty()) { keypress k = keypresses.front(); keypresses.pop_front(); - queue_lock->unlock(); + queue_lock.unlock(); if(k.key1) k.key1->set_state(k.modifiers, k.value); if(k.key2) k.key2->set_state(k.modifiers, k.value); - queue_lock->lock(); + queue_lock.lock(); queue_function_run = true; } //Flush commands. while(!commands.empty()) { std::string c = commands.front(); commands.pop_front(); - queue_lock->unlock(); + queue_lock.unlock(); lsnes_cmd.invoke(c); - queue_lock->lock(); + queue_lock.lock(); queue_function_run = true; } //Flush functions. while(!functions.empty()) { std::pair f = functions.front(); functions.pop_front(); - queue_lock->unlock(); + queue_lock.unlock(); f.first(f.second); - queue_lock->lock(); + queue_lock.lock(); ++functions_executed; queue_function_run = true; } - queue_condition->signal(); + queue_condition.notify_all(); } catch(std::bad_alloc& e) { OOM_panic(); } catch(std::exception& e) { @@ -438,7 +402,7 @@ namespace exit(1); } if(!unlocked) - queue_lock->unlock(); + queue_lock.unlock(); } uint64_t on_idle_time; @@ -457,9 +421,9 @@ void platform::dummy_event_loop() throw() { init_threading(); while(!do_exit_dummy_event_loop) { - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); internal_run_queues(true); - queue_condition->wait(MAXWAIT); + cv_timed_wait(queue_condition, h, microsec_class(MAXWAIT)); } } @@ -467,8 +431,8 @@ void platform::exit_dummy_event_loop() throw() { init_threading(); do_exit_dummy_event_loop = true; - mutex::holder h(*queue_lock); - queue_condition->signal(); + umutex_class h(queue_lock); + queue_condition.notify_all(); usleep(200000); } @@ -491,7 +455,7 @@ void platform::flush_command_queue() throw() reload_lua_timers(); run_idle = false; } - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); internal_run_queues(true); if(!pausing_allowed) break; @@ -512,7 +476,7 @@ void platform::flush_command_queue() throw() if(on_timer_time >= now) waitleft = min(waitleft, on_timer_time - now); if(waitleft > 0) - queue_condition->wait(waitleft); + cv_timed_wait(queue_condition, h, microsec_class(waitleft)); } else break; //If we had to wait, check queues at least once more. @@ -543,7 +507,7 @@ void platform::wait(uint64_t usec) throw() run_idle = false; reload_lua_timers(); } - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); internal_run_queues(true); if(queue_function_run) reload_lua_timers(); @@ -561,7 +525,7 @@ void platform::wait(uint64_t usec) throw() if(on_timer_time >= now) waitleft = min(waitleft, on_timer_time - now); if(waitleft > 0) - queue_condition->wait(waitleft); + cv_timed_wait(queue_condition, h, microsec_class(waitleft)); } else return; } @@ -571,8 +535,8 @@ void platform::cancel_wait() throw() { init_threading(); continue_time = 0; - mutex::holder h(*queue_lock); - queue_condition->signal(); + umutex_class h(queue_lock); + queue_condition.notify_all(); } void platform::set_modal_pause(bool enable) throw() @@ -583,17 +547,17 @@ void platform::set_modal_pause(bool enable) throw() void platform::queue(const keypress& k) throw(std::bad_alloc) { init_threading(); - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); keypresses.push_back(k); - queue_condition->signal(); + queue_condition.notify_all(); } void platform::queue(const std::string& c) throw(std::bad_alloc) { init_threading(); - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); commands.push_back(c); - queue_condition->signal(); + queue_condition.notify_all(); } void platform::queue(void (*f)(void* arg), void* arg, bool sync) throw(std::bad_alloc) @@ -601,13 +565,13 @@ void platform::queue(void (*f)(void* arg), void* arg, bool sync) throw(std::bad_ if(sync && queue_synchronous_fn_warning) std::cerr << "WARNING: Synchronous queue in callback to UI, this may deadlock!" << std::endl; init_threading(); - mutex::holder h(*queue_lock); + umutex_class h(queue_lock); ++next_function; functions.push_back(std::make_pair(f, arg)); - queue_condition->signal(); + queue_condition.notify_all(); if(sync) while(functions_executed < next_function) - queue_condition->wait(10000); + cv_timed_wait(queue_condition, h, microsec_class(10000)); } void platform::run_queues() throw() @@ -617,7 +581,7 @@ void platform::run_queues() throw() namespace { - mutex* _msgbuf_lock; + mutex_class _msgbuf_lock; framebuffer* our_screen; struct painter_listener : public information_dispatch @@ -646,15 +610,9 @@ namespace } } -mutex& platform::msgbuf_lock() throw() +mutex_class& platform::msgbuf_lock() throw() { - if(!_msgbuf_lock) - try { - _msgbuf_lock = &mutex::aquire(); - } catch(...) { - OOM_panic(); - } - return *_msgbuf_lock; + return _msgbuf_lock; } void platform::screen_set_palette(unsigned rshift, unsigned gshift, unsigned bshift) throw() diff --git a/src/dummy/thread.cpp b/src/dummy/thread.cpp index b12d1065..37162782 100644 --- a/src/dummy/thread.cpp +++ b/src/dummy/thread.cpp @@ -1,65 +1,5 @@ #include "core/window.hpp" -struct dummy_mutex : public mutex -{ - ~dummy_mutex() throw(); - void lock() throw(); - void unlock() throw(); -}; - -dummy_mutex::~dummy_mutex() throw() -{ -} - -void dummy_mutex::lock() throw() -{ -} - -void dummy_mutex::unlock() throw() -{ -} - -mutex& mutex::aquire() throw(std::bad_alloc) -{ - return *new dummy_mutex(); -} - -mutex& mutex::aquire_rec() throw(std::bad_alloc) -{ - return *new dummy_mutex(); -} - -struct dummy_condition : public condition -{ - dummy_condition(mutex& m); - ~dummy_condition() throw(); - bool wait(uint64_t x) throw(); - void signal() throw(); -}; - -dummy_condition::dummy_condition(mutex& m) - : condition(m) -{ -} - -dummy_condition::~dummy_condition() throw() -{ -} - -bool dummy_condition::wait(uint64_t x) throw() -{ - return false; -} - -void dummy_condition::signal() throw() -{ -} - -condition& condition::aquire(mutex& m) throw(std::bad_alloc) -{ - return *new dummy_condition(m); -} - struct dummy_thread_id : public thread_id { ~dummy_thread_id() throw(); diff --git a/src/lua/gui-bitmap.cpp b/src/lua/gui-bitmap.cpp index 20644408..11d265a0 100644 --- a/src/lua/gui-bitmap.cpp +++ b/src/lua/gui-bitmap.cpp @@ -1,6 +1,7 @@ #include "lua/internal.hpp" #include "library/framebuffer.hpp" #include "lua/bitmap.hpp" +#include "library/threadtypes.hpp" #include lua_bitmap::lua_bitmap(uint32_t w, uint32_t h) @@ -20,12 +21,10 @@ lua_dbitmap::lua_dbitmap(uint32_t w, uint32_t h) lua_palette::lua_palette() { - palette_mutex = &mutex::aquire(); } lua_palette::~lua_palette() { - delete palette_mutex; } namespace @@ -61,7 +60,7 @@ namespace template void composite_op(struct framebuffer& scr) throw() { if(p) - p->object()->palette_mutex->lock(); + p->object()->palette_mutex.lock(); uint32_t originx = scr.get_origin_x(); uint32_t originy = scr.get_origin_y(); size_t pallim = 0; @@ -101,7 +100,7 @@ namespace b2->object()->pixels[r * b2->object()->width + c].apply(rptr[eptr]); } if(p) - p->object()->palette_mutex->unlock(); + p->object()->palette_mutex.unlock(); } void operator()(struct framebuffer& x) throw() { composite_op(x); } void operator()(struct framebuffer& x) throw() { composite_op(x); } @@ -167,9 +166,9 @@ namespace premultiplied_color nc(nval); //The mutex lock protects only the internals of colors array. if(p->colors.size() <= c) { - p->palette_mutex->lock(); + p->palette_mutex.lock(); p->colors.resize(static_cast(c) + 1); - p->palette_mutex->unlock(); + p->palette_mutex.unlock(); } p->colors[c] = nc; return 0; diff --git a/src/platform/wxwidgets/main.cpp b/src/platform/wxwidgets/main.cpp index 5ce774c4..e31a9f2f 100644 --- a/src/platform/wxwidgets/main.cpp +++ b/src/platform/wxwidgets/main.cpp @@ -18,6 +18,7 @@ #include "core/window.hpp" #include "interface/romtype.hpp" #include "library/string.hpp" +#include "library/threadtypes.hpp" #include "library/zip.hpp" #include "platform/wxwidgets/platform.hpp" @@ -60,8 +61,8 @@ namespace std::string modal_dialog_text; volatile bool modal_dialog_confirm; volatile bool modal_dialog_active; - mutex* ui_mutex; - condition* ui_condition; + mutex_class ui_mutex; + cv_class ui_condition; thread* joystick_thread_handle; void* joystick_thread(void* _args) @@ -113,7 +114,7 @@ namespace std::string text; bool confirm; { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); text = modal_dialog_text; confirm = modal_dialog_confirm; } @@ -126,10 +127,10 @@ namespace main_window); } { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); modal_dialog_confirm = confirm; modal_dialog_active = false; - ui_condition->signal(); + ui_condition.notify_all(); } } else if(c == UISERV_UPDATE_MESSAGES) { if(msg_window) @@ -148,14 +149,14 @@ namespace queue_synchronous_fn_warning = true; back: { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); if(ui_queue.empty()) goto end; i = ui_queue.begin(); } i->fn(i->arg); { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); ui_queue.erase(i); } goto back; @@ -440,8 +441,6 @@ bool lsnes_app::OnInit() bring_app_foreground(); ui_services = new ui_services_type(); - ui_mutex = &mutex::aquire(); - ui_condition = &condition::aquire(*ui_mutex); ui_thread = &thread_id::me(); platform::init(); @@ -577,13 +576,13 @@ void signal_core_change() bool graphics_plugin::modal_message(const std::string& text, bool confirm) throw() { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); modal_dialog_active = true; modal_dialog_confirm = confirm; modal_dialog_text = text; post_ui_event(UISERV_MODAL); while(modal_dialog_active) - ui_condition->wait(10000); + cv_timed_wait(ui_condition, h, microsec_class(10000)); return modal_dialog_confirm; } @@ -603,7 +602,7 @@ void graphics_plugin::fatal_error() throw() void _runuifun_async(void (*fn)(void*), void* arg) { - mutex::holder h(*ui_mutex); + umutex_class h(ui_mutex); ui_queue_entry e; e.fn = fn; e.arg = arg; diff --git a/src/platform/wxwidgets/messages.cpp b/src/platform/wxwidgets/messages.cpp index 05794f02..bae5f91e 100644 --- a/src/platform/wxwidgets/messages.cpp +++ b/src/platform/wxwidgets/messages.cpp @@ -76,7 +76,7 @@ void wxwin_messages::panel::on_paint(wxPaintEvent& e) uint64_t lines, first; std::vector msgs; { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); lines = platform::msgbuf.get_visible_count(); first = platform::msgbuf.get_visible_first(); msgs.resize(lines); @@ -105,37 +105,37 @@ void wxwin_messages::reshow() void wxwin_messages::on_scroll_home(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_beginning(); } void wxwin_messages::on_scroll_pageup(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_up_page(); } void wxwin_messages::on_scroll_lineup(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_up_line(); } void wxwin_messages::on_scroll_linedown(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_down_line(); } void wxwin_messages::on_scroll_pagedown(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_down_page(); } void wxwin_messages::on_scroll_end(wxCommandEvent& e) { - mutex::holder h(platform::msgbuf_lock()); + umutex_class h(platform::msgbuf_lock()); platform::msgbuf.scroll_end(); } diff --git a/src/platform/wxwidgets/thread.cpp b/src/platform/wxwidgets/thread.cpp index 66e1c7ea..627b39e8 100644 --- a/src/platform/wxwidgets/thread.cpp +++ b/src/platform/wxwidgets/thread.cpp @@ -2,133 +2,6 @@ #include -struct wxw_mutex : public mutex -{ - wxw_mutex() throw(std::bad_alloc); - ~wxw_mutex() throw(); - void lock() throw(); - void unlock() throw(); - wxMutex* m; -}; - -struct wxw_rec_mutex : public mutex -{ - wxw_rec_mutex() throw(std::bad_alloc); - ~wxw_rec_mutex() throw(); - void lock() throw(); - void unlock() throw(); - wxMutex* m; - volatile bool locked; - uint32_t owner; - uint32_t count; -}; - -wxw_mutex::wxw_mutex() throw(std::bad_alloc) -{ - m = new wxMutex(); -} - -wxw_mutex::~wxw_mutex() throw() -{ - delete m; -} - -void wxw_mutex::lock() throw() -{ - m->Lock(); -} - -void wxw_mutex::unlock() throw() -{ - m->Unlock(); -} - -wxw_rec_mutex::wxw_rec_mutex() throw(std::bad_alloc) -{ - m = new wxMutex(); - locked = false; - owner = 0; - count = 0; -} - -wxw_rec_mutex::~wxw_rec_mutex() throw() -{ - delete m; -} - -void wxw_rec_mutex::lock() throw() -{ - uint32_t our_id = wxThread::GetCurrentId(); - if(locked && owner == our_id) { - //Owned by us, increment lock count. - ++count; - return; - } - m->Lock(); - locked = true; - owner = our_id; - count = 1; -} - -void wxw_rec_mutex::unlock() throw() -{ - uint32_t our_id = wxThread::GetCurrentId(); - if(!locked || owner != our_id) - std::cerr << "Warning: Trying to unlock recursive lock locked by another thread!" << std::endl; - if(!--count) { - locked = false; - owner = 0; - m->Unlock(); - } -} - -mutex& mutex::aquire() throw(std::bad_alloc) -{ - return *new wxw_mutex; -} - -mutex& mutex::aquire_rec() throw(std::bad_alloc) -{ - return *new wxw_rec_mutex; -} - -struct wxw_condition : public condition -{ - wxw_condition(mutex& m) throw(std::bad_alloc); - ~wxw_condition() throw(); - bool wait(uint64_t x) throw(); - void signal() throw(); - wxCondition* c; -}; - -wxw_condition::wxw_condition(mutex& m) throw(std::bad_alloc) - : condition(m) -{ - wxw_mutex* m2 = dynamic_cast(&m); - c = new wxCondition(*m2->m); -} - -wxw_condition::~wxw_condition() throw() -{ - delete c; -} - -bool wxw_condition::wait(uint64_t x) throw() -{ - wxCondError e = c->WaitTimeout((x + 999) / 1000); - return (e == wxCOND_NO_ERROR); -} - -void wxw_condition::signal() throw() -{ - c->Broadcast(); -} - -condition& condition::aquire(mutex& m) throw(std::bad_alloc) -{ - return *new wxw_condition(m); -} - struct wxw_thread_id : public thread_id { wxw_thread_id() throw();