Use system mutex/condition types instead of platform ones
This commit is contained in:
parent
0186929e64
commit
8578b8812a
12 changed files with 87 additions and 376 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,11 @@ typedef std::thread thread_class;
|
|||
typedef std::condition_variable cv_class;
|
||||
typedef std::mutex mutex_class;
|
||||
typedef std::unique_lock<std::mutex> 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 <boost/thread.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
@ -18,6 +23,11 @@ typedef boost::thread thread_class;
|
|||
typedef boost::condition_variable cv_class;
|
||||
typedef boost::mutex mutex_class;
|
||||
typedef boost::unique_lock<boost::mutex> 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
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <cstdint>
|
||||
#include "core/window.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#include "library/threadtypes.hpp"
|
||||
|
||||
struct lua_bitmap
|
||||
{
|
||||
|
@ -28,7 +29,7 @@ struct lua_palette
|
|||
std::vector<premultiplied_color> colors;
|
||||
lua_palette();
|
||||
~lua_palette();
|
||||
mutex* palette_mutex;
|
||||
mutex_class palette_mutex;
|
||||
};
|
||||
|
||||
struct lua_loaded_bitmap
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "library/framebuffer.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/threadtypes.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
@ -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<keypress> keypresses;
|
||||
std::deque<std::string> commands;
|
||||
std::deque<std::pair<void(*)(void*), void*>> 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<void(*)(void*), void*> 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<false>* 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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "lua/internal.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#include "lua/bitmap.hpp"
|
||||
#include "library/threadtypes.hpp"
|
||||
#include <vector>
|
||||
|
||||
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<bool T> void composite_op(struct framebuffer<T>& 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<false>& x) throw() { composite_op(x); }
|
||||
void operator()(struct framebuffer<true>& 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<uint32_t>(c) + 1);
|
||||
p->palette_mutex->unlock();
|
||||
p->palette_mutex.unlock();
|
||||
}
|
||||
p->colors[c] = nc;
|
||||
return 0;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -76,7 +76,7 @@ void wxwin_messages::panel::on_paint(wxPaintEvent& e)
|
|||
uint64_t lines, first;
|
||||
std::vector<std::string> 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,133 +2,6 @@
|
|||
|
||||
#include <wx/thread.h>
|
||||
|
||||
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<wxw_mutex*>(&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();
|
||||
|
|
Loading…
Add table
Reference in a new issue