BACKENDS: Refactor the API for creating Mutexes

This commit is contained in:
Cameron Cawley 2021-08-24 23:53:21 +01:00 committed by Eugene Sandulenko
parent dcd537337b
commit 5022489277
40 changed files with 341 additions and 336 deletions

View file

@ -25,7 +25,6 @@
#include "backends/audiocd/audiocd.h"
#include "backends/graphics/graphics.h"
#include "backends/mixer/mixer.h"
#include "backends/mutex/mutex.h"
#include "gui/EventRecorder.h"
#include "common/timer.h"
@ -316,37 +315,3 @@ Audio::Mixer *ModularMixerBackend::getMixer() {
return getMixerManager()->getMixer();
}
ModularMutexBackend::ModularMutexBackend()
:
_mutexManager(0) {
}
ModularMutexBackend::~ModularMutexBackend() {
// _timerManager needs to be deleted before _mutexManager to avoid a crash.
delete _timerManager;
_timerManager = 0;
delete _mutexManager;
_mutexManager = 0;
}
OSystem::MutexRef ModularMutexBackend::createMutex() {
assert(_mutexManager);
return _mutexManager->createMutex();
}
void ModularMutexBackend::lockMutex(MutexRef mutex) {
assert(_mutexManager);
_mutexManager->lockMutex(mutex);
}
void ModularMutexBackend::unlockMutex(MutexRef mutex) {
assert(_mutexManager);
_mutexManager->unlockMutex(mutex);
}
void ModularMutexBackend::deleteMutex(MutexRef mutex) {
assert(_mutexManager);
_mutexManager->deleteMutex(mutex);
}

View file

@ -27,7 +27,6 @@
class GraphicsManager;
class MixerManager;
class MutexManager;
/**
* Base classes for modular backends.
@ -38,6 +37,7 @@ class MutexManager;
* A backend derivated from these classes, will need to implement
* these functions on its own:
* OSystem::pollEvent()
* OSystem::createMutex()
* OSystem::getMillis()
* OSystem::delayMillis()
* OSystem::getTimeAndDate()
@ -165,28 +165,4 @@ protected:
//@}
};
class ModularMutexBackend : virtual public BaseBackend {
public:
ModularMutexBackend();
virtual ~ModularMutexBackend();
/** @name Mutex handling */
//@{
virtual MutexRef createMutex() override final;
virtual void lockMutex(MutexRef mutex) override final;
virtual void unlockMutex(MutexRef mutex) override final;
virtual void deleteMutex(MutexRef mutex) override final;
//@}
protected:
/** @name Managers variables */
//@{
MutexManager *_mutexManager;
//@}
};
#endif

View file

@ -224,6 +224,11 @@ endif
endif
ifeq ($(BACKEND),3ds)
MODULE_OBJS += \
mutex/3ds/3ds-mutex.o
endif
ifeq ($(BACKEND),android)
MODULE_OBJS += \
mutex/pthread/pthread-mutex.o
@ -371,6 +376,7 @@ ifeq ($(BACKEND),wii)
MODULE_OBJS += \
fs/wii/wii-fs.o \
fs/wii/wii-fs-factory.o \
mutex/wii/wii-mutex.o \
plugins/wii/wii-provider.o
endif

View file

@ -0,0 +1,54 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#include "common/scummsys.h"
#if defined(__3DS__)
#include "backends/mutex/3ds/3ds-mutex.h"
#include <3ds.h>
/**
* 3DS mutex manager
*/
class _3DSMutexInternal final : public Common::MutexInternal {
public:
_3DSMutexInternal() { RecursiveLock_Init(&_mutex); }
virtual ~_3DSMutexInternal() override {}
virtual bool lock() override { RecursiveLock_Lock(&_mutex); return true; }
virtual bool unlock() override { RecursiveLock_Unlock(&_mutex); return true; }
private:
RecursiveLock _mutex;
};
Common::MutexInternal *create3DSMutexInternal() {
return new _3DSMutexInternal();
}
#endif

View file

@ -20,24 +20,11 @@
*
*/
#ifndef BACKENDS_MUTEX_ABSTRACT_H
#define BACKENDS_MUTEX_ABSTRACT_H
#ifndef BACKENDS_MUTEX_3DS_H
#define BACKENDS_MUTEX_3DS_H
#include "common/system.h"
#include "common/noncopyable.h"
#include "common/mutex.h"
/**
* Abstract class for mutex manager. Subclasses
* implement the real functionality.
*/
class MutexManager : Common::NonCopyable {
public:
virtual ~MutexManager() {}
virtual OSystem::MutexRef createMutex() = 0;
virtual void lockMutex(OSystem::MutexRef mutex) = 0;
virtual void unlockMutex(OSystem::MutexRef mutex) = 0;
virtual void deleteMutex(OSystem::MutexRef mutex) = 0;
};
Common::MutexInternal *create3DSMutexInternal();
#endif

View file

@ -23,17 +23,17 @@
#ifndef BACKENDS_MUTEX_NULL_H
#define BACKENDS_MUTEX_NULL_H
#include "backends/mutex/mutex.h"
#include "common/mutex.h"
/**
* Null mutex manager
*/
class NullMutexManager : public MutexManager {
class NullMutexInternal final : public Common::MutexInternal {
public:
virtual OSystem::MutexRef createMutex() { return OSystem::MutexRef(); }
virtual void lockMutex(OSystem::MutexRef mutex) {}
virtual void unlockMutex(OSystem::MutexRef mutex) {}
virtual void deleteMutex(OSystem::MutexRef mutex) {}
NullMutexInternal() {}
virtual ~NullMutexInternal() {}
virtual bool lock() { return true; }
virtual bool unlock() { return true; }
};
#endif

View file

@ -30,41 +30,58 @@
#include <pthread.h>
/**
* pthreads mutex implementation
*/
class PthreadMutexInternal final : public Common::MutexInternal {
public:
PthreadMutexInternal();
virtual ~PthreadMutexInternal() override;
OSystem::MutexRef PthreadMutexManager::createMutex() {
virtual bool lock() override;
virtual bool unlock() override;
private:
pthread_mutex_t _mutex;
};
PthreadMutexInternal::PthreadMutexInternal() {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_t *mutex = new pthread_mutex_t;
if (pthread_mutex_init(mutex, &attr) != 0) {
if (pthread_mutex_init(&_mutex, &attr) != 0) {
warning("pthread_mutex_init() failed");
delete mutex;
return NULL;
}
return (OSystem::MutexRef)mutex;
}
void PthreadMutexManager::lockMutex(OSystem::MutexRef mutex) {
if (pthread_mutex_lock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_lock() failed");
}
void PthreadMutexManager::unlockMutex(OSystem::MutexRef mutex) {
if (pthread_mutex_unlock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_unlock() failed");
}
void PthreadMutexManager::deleteMutex(OSystem::MutexRef mutex) {
pthread_mutex_t *m = (pthread_mutex_t *)mutex;
if (pthread_mutex_destroy(m) != 0)
PthreadMutexInternal::~PthreadMutexInternal() {
if (pthread_mutex_destroy(&_mutex) != 0)
warning("pthread_mutex_destroy() failed");
else
delete m;
}
bool PthreadMutexInternal::lock() {
if (pthread_mutex_lock(&_mutex) != 0) {
warning("pthread_mutex_lock() failed");
return false;
} else {
return true;
}
}
bool PthreadMutexInternal::unlock() {
if (pthread_mutex_unlock(&_mutex) != 0) {
warning("pthread_mutex_unlock() failed");
return false;
} else {
return true;
}
}
Common::MutexInternal *createPthreadMutexInternal() {
return new PthreadMutexInternal();
}
#endif

View file

@ -23,18 +23,8 @@
#ifndef BACKENDS_MUTEX_PTHREAD_H
#define BACKENDS_MUTEX_PTHREAD_H
#include "backends/mutex/mutex.h"
/**
* pthreads mutex manager
*/
class PthreadMutexManager : public MutexManager {
public:
virtual OSystem::MutexRef createMutex() override;
virtual void lockMutex(OSystem::MutexRef mutex) override;
virtual void unlockMutex(OSystem::MutexRef mutex) override;
virtual void deleteMutex(OSystem::MutexRef mutex) override;
};
#include "common/mutex.h"
Common::MutexInternal *createPthreadMutexInternal();
#endif

View file

@ -27,21 +27,23 @@
#include "backends/mutex/sdl/sdl-mutex.h"
#include "backends/platform/sdl/sdl-sys.h"
/**
* SDL mutex manager
*/
class SdlMutexInternal final : public Common::MutexInternal {
public:
SdlMutexInternal() { _mutex = SDL_CreateMutex(); }
virtual ~SdlMutexInternal() override { SDL_DestroyMutex(_mutex); }
OSystem::MutexRef SdlMutexManager::createMutex() {
return (OSystem::MutexRef) SDL_CreateMutex();
}
virtual bool lock() override { return (SDL_mutexP(_mutex) == 0); }
virtual bool unlock() override { return (SDL_mutexV(_mutex) == 0); }
void SdlMutexManager::lockMutex(OSystem::MutexRef mutex) {
SDL_mutexP((SDL_mutex *)mutex);
}
private:
SDL_mutex *_mutex;
};
void SdlMutexManager::unlockMutex(OSystem::MutexRef mutex) {
SDL_mutexV((SDL_mutex *)mutex);
}
void SdlMutexManager::deleteMutex(OSystem::MutexRef mutex) {
SDL_DestroyMutex((SDL_mutex *)mutex);
Common::MutexInternal *createSdlMutexInternal() {
return new SdlMutexInternal();
}
#endif

View file

@ -23,18 +23,8 @@
#ifndef BACKENDS_MUTEX_SDL_H
#define BACKENDS_MUTEX_SDL_H
#include "backends/mutex/mutex.h"
/**
* SDL mutex manager
*/
class SdlMutexManager : public MutexManager {
public:
virtual OSystem::MutexRef createMutex();
virtual void lockMutex(OSystem::MutexRef mutex);
virtual void unlockMutex(OSystem::MutexRef mutex);
virtual void deleteMutex(OSystem::MutexRef mutex);
};
#include "common/mutex.h"
Common::MutexInternal *createSdlMutexInternal();
#endif

View file

@ -0,0 +1,90 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/scummsys.h"
#if defined(__WII__)
#include "backends/mutex/wii/wii-mutex.h"
#include <ogc/mutex.h>
/**
* Wii mutex implementation
*/
class WiiMutexInternal final : public Common::MutexInternal {
public:
WiiMutexInternal();
virtual ~WiiMutexInternal() override;
virtual bool lock() override;
virtual bool unlock() override;
private:
mutex_t _mutex;
};
WiiMutexInternal::WiiMutexInternal() {
s32 res = LWP_MutexInit(&_mutex, true);
if (res) {
printf("ERROR creating mutex\n");
}
}
WiiMutexInternal::~WiiMutexInternal() {
s32 res = LWP_MutexDestroy(_mutex);
if (res)
printf("ERROR destroying mutex (%d)\n", res);
}
bool WiiMutexInternal::lock() {
s32 res = LWP_MutexLock(_mutex);
if (res) {
printf("ERROR locking mutex (%d)\n", res);
return false;
} else {
return true;
}
}
bool WiiMutexInternal::unlock() {
s32 res = LWP_MutexUnlock(_mutex);
if (res) {
printf("ERROR unlocking mutex (%d)\n", res);
return false;
} else {
return true;
}
}
Common::MutexInternal *createWiiMutexInternal() {
return new WiiMutexInternal();
}
#endif

View file

@ -0,0 +1,30 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef BACKENDS_MUTEX_WII_H
#define BACKENDS_MUTEX_WII_H
#include "common/mutex.h"
Common::MutexInternal *createWiiMutexInternal();
#endif

View file

@ -28,6 +28,7 @@
#include "osystem.h"
#include "backends/platform/3ds/config.h"
#include "backends/mutex/3ds/3ds-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "backends/events/default/default-events.h"
@ -198,19 +199,8 @@ void OSystem_3DS::getTimeAndDate(TimeDate& td, bool skipRecord) const {
td.tm_wday = t.tm_wday;
}
OSystem::MutexRef OSystem_3DS::createMutex() {
RecursiveLock *mutex = new RecursiveLock();
RecursiveLock_Init(mutex);
return (OSystem::MutexRef) mutex;
}
void OSystem_3DS::lockMutex(MutexRef mutex) {
RecursiveLock_Lock((RecursiveLock*)mutex);
}
void OSystem_3DS::unlockMutex(MutexRef mutex) {
RecursiveLock_Unlock((RecursiveLock*)mutex);
}
void OSystem_3DS::deleteMutex(MutexRef mutex) {
delete (RecursiveLock*)mutex;
Common::MutexInternal *OSystem_3DS::createMutex() {
return create3DSMutexInternal();
}
Common::String OSystem_3DS::getSystemLanguage() const {

View file

@ -25,7 +25,6 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#include "backends/mutex/mutex.h"
#include "backends/base-backend.h"
#include "graphics/palette.h"
#include "base/main.h"
@ -118,10 +117,7 @@ public:
virtual void delayMillis(uint msecs);
virtual void getTimeAndDate(TimeDate &td, bool skipRecord = false) const;
virtual MutexRef createMutex();
virtual void lockMutex(MutexRef mutex);
virtual void unlockMutex(MutexRef mutex);
virtual void deleteMutex(MutexRef mutex);
virtual Common::MutexInternal *createMutex();
virtual void logMessage(LogMessageType::Type type, const char *message);

View file

@ -425,7 +425,6 @@ void OSystem_Android::initBackend() {
// TODO remove the debug message eventually
LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
_mutexManager = new PthreadMutexManager();
_timerManager = new DefaultTimerManager();
_event_queue_lock = new Common::Mutex();
@ -559,6 +558,10 @@ void OSystem_Android::delayMillis(uint msecs) {
usleep(msecs * 1000);
}
Common::MutexInternal *OSystem_Android::createMutex() {
return createPthreadMutexInternal();
}
void OSystem_Android::quit() {
ENTER();

View file

@ -57,7 +57,7 @@ extern const char *android_log_tag;
#define ENTER(fmt, args...) do { } while (false)
#endif
class OSystem_Android : public ModularMutexBackend, public ModularGraphicsBackend, Common::EventSource {
class OSystem_Android : public ModularGraphicsBackend, Common::EventSource {
private:
// passed from the dark side
int _audio_sample_rate;
@ -129,6 +129,7 @@ public:
virtual uint32 getMillis(bool skipRecord = false) override;
virtual void delayMillis(uint msecs) override;
virtual Common::MutexInternal *createMutex() override;
virtual void quit() override;

View file

@ -362,7 +362,6 @@ void OSystem_Android::initBackend() {
// TODO remove the debug message eventually
LOGD("Setting DefaultSaveFileManager path to: %s", ConfMan.get("savepath").c_str());
_mutexManager = new PthreadMutexManager();
_timerManager = new DefaultTimerManager();
_event_queue_lock = new Common::Mutex();
@ -476,6 +475,10 @@ void OSystem_Android::delayMillis(uint msecs) {
usleep(msecs * 1000);
}
Common::MutexInternal *OSystem_Android::createMutex() {
return createPthreadMutexInternal();
}
void OSystem_Android::quit() {
ENTER();

View file

@ -102,7 +102,7 @@ extern void checkGlError(const char *expr, const char *file, int line);
#define GLTHREADCHECK do { } while (false)
#endif
class OSystem_Android : public ModularMutexBackend, public ModularGraphicsBackend, Common::EventSource {
class OSystem_Android : public ModularGraphicsBackend, Common::EventSource {
private:
// passed from the dark side
int _audio_sample_rate;
@ -172,6 +172,7 @@ public:
virtual uint32 getMillis(bool skipRecord = false);
virtual void delayMillis(uint msecs);
virtual Common::MutexInternal *createMutex();
virtual void quit();

View file

@ -163,10 +163,7 @@ public:
virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12); }
// Mutex handling
MutexRef createMutex();
void lockMutex(MutexRef mutex);
void unlockMutex(MutexRef mutex);
void deleteMutex(MutexRef mutex);
Common::MutexInternal *createMutex();
// Set a window caption or any other comparable status display to the
// given value.

View file

@ -30,6 +30,7 @@
#include "dcutils.h"
#include "icon.h"
#include "DCLauncherDialog.h"
#include "backends/mutex/null/null-mutex.h"
#include <common/config-manager.h>
#include <common/memstream.h>
#include <common/endian.h>
@ -153,24 +154,11 @@ void OSystem_Dreamcast::quit() {
}
/* Mutex handling */
OSystem::MutexRef OSystem_Dreamcast::createMutex()
Common::MutexInternal *OSystem_Dreamcast::createMutex()
{
return NULL;
return new NullMutexInternal();
}
void OSystem_Dreamcast::lockMutex(MutexRef mutex)
{
}
void OSystem_Dreamcast::unlockMutex(MutexRef mutex)
{
}
void OSystem_Dreamcast::deleteMutex(MutexRef mutex)
{
}
/* Features */
bool OSystem_Dreamcast::hasFeature(Feature f)
{

View file

@ -56,7 +56,6 @@ OSystem_DS::OSystem_DS()
nitroFSInit(NULL);
_fsFactory = new DevoptabFilesystemFactory();
_mutexManager = new NullMutexManager();
}
OSystem_DS::~OSystem_DS() {
@ -129,6 +128,10 @@ void OSystem_DS::getTimeAndDate(TimeDate &td, bool skipRecord) const {
td.tm_wday = t.tm_wday;
}
Common::MutexInternal *OSystem_DS::createMutex() {
return new NullMutexInternal();
}
void OSystem_DS::quit() {
}

View file

@ -38,7 +38,7 @@ enum {
GFX_SWSCALE = 2
};
class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
class OSystem_DS : public ModularMixerBackend, public PaletteManager {
protected:
DS::Background _framebuffer, _overlay;
#ifdef DISABLE_TEXT_CONSOLE
@ -130,6 +130,7 @@ public:
virtual void delayMillis(uint msecs);
virtual void getTimeAndDate(TimeDate &td, bool skipRecord = false) const;
void doTimerCallback(int interval = 10);
virtual Common::MutexInternal *createMutex();
virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
virtual Common::HardwareInputSet *getHardwareInputSet();

View file

@ -131,8 +131,6 @@ int OSystem_iOS7::timerHandler(int t) {
}
void OSystem_iOS7::initBackend() {
_mutexManager = new PthreadMutexManager();
#ifdef IPHONE_SANDBOXED
_savefileManager = new SandboxedSaveFileManager(_chrootBasePath, "/Savegames");
#else
@ -309,6 +307,10 @@ void OSystem_iOS7::setTimerCallback(TimerProc callback, int interval) {
_timerCallback = NULL;
}
Common::MutexInternal *OSystem_iOS7::createMutex() {
return createPthreadMutexInternal();
}
void OSystem_iOS7::quit() {
}

View file

@ -53,7 +53,7 @@ struct AQCallbackStruct {
AudioStreamBasicDescription dataFormat;
};
class OSystem_iOS7 : public EventsBaseBackend, public ModularMutexBackend, public PaletteManager {
class OSystem_iOS7 : public EventsBaseBackend, public PaletteManager {
protected:
static AQCallbackStruct s_AudioQueue;
static SoundProc s_soundCallback;
@ -180,6 +180,7 @@ public:
virtual bool pollEvent(Common::Event &event) override;
virtual uint32 getMillis(bool skipRecord = false) override;
virtual void delayMillis(uint msecs) override;
virtual Common::MutexInternal *createMutex() override;
static void mixCallback(void *sys, byte *samples, int len);
virtual void setupMixer(void);

View file

@ -84,8 +84,6 @@ int OSystem_IPHONE::timerHandler(int t) {
}
void OSystem_IPHONE::initBackend() {
_mutexManager = new PthreadMutexManager();
#ifdef IPHONE_SANDBOXED
_savefileManager = new DefaultSaveFileManager(iPhone_getDocumentsDir());
#else
@ -195,6 +193,10 @@ void OSystem_IPHONE::setTimerCallback(TimerProc callback, int interval) {
_timerCallback = NULL;
}
Common::MutexInternal *OSystem_IPHONE::createMutex() {
return createPthreadMutexInternal();
}
void OSystem_IPHONE::quit() {
}

View file

@ -51,7 +51,7 @@ struct AQCallbackStruct {
AudioStreamBasicDescription dataFormat;
};
class OSystem_IPHONE : public EventsBaseBackend, public ModularMutexBackend, public PaletteManager {
class OSystem_IPHONE : public EventsBaseBackend, public PaletteManager {
protected:
static AQCallbackStruct s_AudioQueue;
static SoundProc s_soundCallback;
@ -165,6 +165,7 @@ public:
virtual bool pollEvent(Common::Event &event);
virtual uint32 getMillis(bool skipRecord = false);
virtual void delayMillis(uint msecs);
virtual Common::MutexInternal *createMutex();
static void mixCallback(void *sys, byte *samples, int len);
virtual void setupMixer(void);

View file

@ -187,10 +187,7 @@ public:
virtual uint32 getMillis(bool skipRecord = false);
virtual void delayMillis(uint msecs);
virtual MutexRef createMutex(void);
virtual void lockMutex(MutexRef mutex);
virtual void unlockMutex(MutexRef mutex);
virtual void deleteMutex(MutexRef mutex);
virtual Common::MutexInternal *createMutex(void);
virtual void quit();

View file

@ -30,6 +30,7 @@
#include "pakfs_save_manager.h"
#include "framfs_save_manager.h"
#include "backends/fs/n64/n64-fs-factory.h"
#include "backends/mutex/null/null-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "graphics/conversion.h"
@ -812,20 +813,8 @@ void OSystem_N64::delayMillis(uint msecs) {
}
// As we don't have multi-threading, no need for mutexes
OSystem::MutexRef OSystem_N64::createMutex(void) {
return NULL;
}
void OSystem_N64::lockMutex(MutexRef mutex) {
return;
}
void OSystem_N64::unlockMutex(MutexRef mutex) {
return;
}
void OSystem_N64::deleteMutex(MutexRef mutex) {
return;
Common::MutexInternal *OSystem_N64::createMutex(void) {
return new NullMutexInternal();
}
void OSystem_N64::quit() {

View file

@ -49,6 +49,7 @@ typedef void (*sighandler_t)(int);
#if defined(USE_NULL_DRIVER)
#include "backends/modular-backend.h"
#include "backends/mutex/null/null-mutex.h"
#include "base/main.h"
#ifndef NULL_DRIVER_USE_FOR_TEST
@ -56,7 +57,6 @@ typedef void (*sighandler_t)(int);
#include "backends/timer/default/default-timer.h"
#include "backends/events/default/default-events.h"
#include "backends/mixer/null/null-mixer.h"
#include "backends/mutex/null/null-mutex.h"
#include "backends/graphics/null/null-graphics.h"
#include "gui/debugger.h"
#endif
@ -76,7 +76,7 @@ typedef void (*sighandler_t)(int);
#include "backends/fs/windows/windows-fs-factory.h"
#endif
class OSystem_NULL : public ModularMutexBackend, public ModularMixerBackend, public ModularGraphicsBackend, Common::EventSource {
class OSystem_NULL : public ModularMixerBackend, public ModularGraphicsBackend, Common::EventSource {
public:
OSystem_NULL();
virtual ~OSystem_NULL();
@ -85,6 +85,7 @@ public:
virtual bool pollEvent(Common::Event &event);
virtual Common::MutexInternal *createMutex();
virtual uint32 getMillis(bool skipRecord = false);
virtual void delayMillis(uint msecs);
virtual void getTimeAndDate(TimeDate &td, bool skipRecord = false) const;
@ -145,7 +146,6 @@ void OSystem_NULL::initBackend() {
last_handler = signal(SIGINT, intHandler);
#endif
_mutexManager = new NullMutexManager();
_timerManager = new DefaultTimerManager();
_eventManager = new DefaultEventManager(this);
_savefileManager = new DefaultSaveFileManager();
@ -185,6 +185,10 @@ bool OSystem_NULL::pollEvent(Common::Event &event) {
return false;
}
Common::MutexInternal *OSystem_NULL::createMutex() {
return new NullMutexInternal();
}
uint32 OSystem_NULL::getMillis(bool skipRecord) {
#ifdef POSIX
timeval curTime;

View file

@ -358,20 +358,8 @@ void OSystem_PSP::delayMillis(uint msecs) {
PspThread::delayMillis(msecs);
}
OSystem::MutexRef OSystem_PSP::createMutex(void) {
return (MutexRef) new PspMutex(true); // start with a full mutex
}
void OSystem_PSP::lockMutex(MutexRef mutex) {
((PspMutex *)mutex)->lock();
}
void OSystem_PSP::unlockMutex(MutexRef mutex) {
((PspMutex *)mutex)->unlock();
}
void OSystem_PSP::deleteMutex(MutexRef mutex) {
delete (PspMutex *)mutex;
Common::MutexInternal *OSystem_PSP::createMutex(void) {
return new PspMutex(true); // start with a full mutex
}
void OSystem_PSP::mixCallback(void *sys, byte *samples, int len) {

View file

@ -126,10 +126,7 @@ public:
void delayMillis(uint msecs);
// Mutex
MutexRef createMutex(void);
void lockMutex(MutexRef mutex);
void unlockMutex(MutexRef mutex);
void deleteMutex(MutexRef mutex);
Common::MutexInternal *createMutex(void);
// Sound
static void mixCallback(void *sys, byte *samples, int len);

View file

@ -24,7 +24,7 @@
#define PSP_THREAD_H
#include <pspthreadman.h>
#include "common/scummsys.h"
#include "common/mutex.h"
// class to inherit for creating threads
class PspThreadable {
@ -60,7 +60,7 @@ public:
int getValue();
};
class PspMutex {
class PspMutex : public Common::MutexInternal {
private:
PspSemaphore _semaphore;
int _recursiveCount;

View file

@ -133,8 +133,6 @@ OSystem_SDL::~OSystem_SDL() {
#endif
_timerManager = 0;
delete _mutexManager;
_mutexManager = 0;
delete _logger;
_logger = 0;
@ -163,11 +161,6 @@ void OSystem_SDL::init() {
// Disable OS cursor
SDL_ShowCursor(SDL_DISABLE);
// Creates the early needed managers, if they don't exist yet
// (we check for this to allow subclasses to provide their own).
if (_mutexManager == 0)
_mutexManager = new SdlMutexManager();
if (_window == 0)
_window = new SdlWindow();
@ -650,6 +643,10 @@ bool OSystem_SDL::openUrl(const Common::String &url) {
}
#endif
Common::MutexInternal *OSystem_SDL::createMutex() {
return createSdlMutexInternal();
}
uint32 OSystem_SDL::getMillis(bool skipRecord) {
uint32 millis = SDL_GetTicks();

View file

@ -40,7 +40,7 @@ class DiscordPresence;
/**
* Base OSystem class for all SDL ports.
*/
class OSystem_SDL : public ModularMutexBackend, public ModularMixerBackend, public ModularGraphicsBackend {
class OSystem_SDL : public ModularMixerBackend, public ModularGraphicsBackend {
public:
OSystem_SDL();
virtual ~OSystem_SDL();
@ -83,6 +83,7 @@ public:
virtual void setWindowCaption(const Common::U32String &caption) override;
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) override;
virtual Common::MutexInternal *createMutex() override;
virtual uint32 getMillis(bool skipRecord = false) override;
virtual void delayMillis(uint msecs) override;
virtual void getTimeAndDate(TimeDate &td, bool skipRecord = false) const override;

View file

@ -25,12 +25,12 @@
#include <unistd.h>
#include <ogc/conf.h>
#include <ogc/mutex.h>
#include <ogc/lwp_watchdog.h>
#include "common/config-manager.h"
#include "common/textconsole.h"
#include "backends/fs/wii/wii-fs-factory.h"
#include "backends/mutex/wii/wii-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
@ -221,40 +221,8 @@ void OSystem_Wii::delayMillis(uint msecs) {
usleep(msecs * 1000);
}
OSystem::MutexRef OSystem_Wii::createMutex() {
mutex_t *mutex = (mutex_t *) malloc(sizeof(mutex_t));
s32 res = LWP_MutexInit(mutex, true);
if (res) {
printf("ERROR creating mutex\n");
free(mutex);
return NULL;
}
return (MutexRef) mutex;
}
void OSystem_Wii::lockMutex(MutexRef mutex) {
s32 res = LWP_MutexLock(*(mutex_t *)mutex);
if (res)
printf("ERROR locking mutex %p (%d)\n", mutex, res);
}
void OSystem_Wii::unlockMutex(MutexRef mutex) {
s32 res = LWP_MutexUnlock(*(mutex_t *)mutex);
if (res)
printf("ERROR unlocking mutex %p (%d)\n", mutex, res);
}
void OSystem_Wii::deleteMutex(MutexRef mutex) {
s32 res = LWP_MutexDestroy(*(mutex_t *)mutex);
if (res)
printf("ERROR destroying mutex %p (%d)\n", mutex, res);
free(mutex);
Common::MutexInternal *OSystem_Wii::createMutex() {
return createWiiMutexInternal();
}
Audio::Mixer *OSystem_Wii::getMixer() {

View file

@ -197,10 +197,7 @@ public:
virtual uint32 getMillis(bool skipRecord = false) override;
virtual void delayMillis(uint msecs) override;
virtual MutexRef createMutex() override;
virtual void lockMutex(MutexRef mutex) override;
virtual void unlockMutex(MutexRef mutex) override;
virtual void deleteMutex(MutexRef mutex) override;
virtual Common::MutexInternal *createMutex() override;
typedef void (*SoundProc)(void *param, byte *buf, int len);

View file

@ -29,11 +29,7 @@
#include "common/textconsole.h"
OSystem::MutexRef timerMutex;
static Uint32 timer_handler(Uint32 interval, void *param) {
Common::StackLock lock(timerMutex);
((DefaultTimerManager *)param)->handler();
return interval;
}
@ -49,8 +45,6 @@ SdlTimerManager::SdlTimerManager() {
}
SdlTimerManager::~SdlTimerManager() {
Common::StackLock lock(timerMutex);
// Removes the timer callback
SDL_RemoveTimer(_timerID);

View file

@ -32,22 +32,22 @@ Mutex::Mutex() {
}
Mutex::~Mutex() {
g_system->deleteMutex(_mutex);
delete _mutex;
}
void Mutex::lock() {
g_system->lockMutex(_mutex);
bool Mutex::lock() {
return _mutex->lock();
}
void Mutex::unlock() {
g_system->unlockMutex(_mutex);
bool Mutex::unlock() {
return _mutex->unlock();
}
#pragma mark -
StackLock::StackLock(OSystem::MutexRef mutex, const char *mutexName)
StackLock::StackLock(MutexInternal *mutex, const char *mutexName)
: _mutex(mutex), _mutexName(mutexName) {
lock();
}
@ -61,18 +61,18 @@ StackLock::~StackLock() {
unlock();
}
void StackLock::lock() {
bool StackLock::lock() {
if (_mutexName != nullptr)
debug(6, "Locking mutex %s", _mutexName);
g_system->lockMutex(_mutex);
return _mutex->lock();
}
void StackLock::unlock() {
bool StackLock::unlock() {
if (_mutexName != nullptr)
debug(6, "Unlocking mutex %s", _mutexName);
g_system->unlockMutex(_mutex);
return _mutex->unlock();
}
} // End of namespace Common

View file

@ -38,17 +38,25 @@ namespace Common {
class Mutex;
class MutexInternal {
public:
virtual ~MutexInternal() {}
virtual bool lock() = 0;
virtual bool unlock() = 0;
};
/**
* Auxillary class to (un)lock a mutex on the stack.
*/
class StackLock {
OSystem::MutexRef _mutex;
MutexInternal *_mutex;
const char *_mutexName;
void lock();
void unlock();
bool lock();
bool unlock();
public:
explicit StackLock(OSystem::MutexRef mutex, const char *mutexName = nullptr);
explicit StackLock(MutexInternal *mutex, const char *mutexName = nullptr);
explicit StackLock(const Mutex &mutex, const char *mutexName = nullptr);
~StackLock();
};
@ -60,14 +68,14 @@ public:
class Mutex {
friend class StackLock;
OSystem::MutexRef _mutex;
MutexInternal *_mutex;
public:
Mutex();
~Mutex();
void lock();
void unlock();
bool lock();
bool unlock();
};
/** @} */

View file

@ -47,6 +47,7 @@ class OptionsContainerWidget;
namespace Common {
class EventManager;
class MutexInternal;
struct Rect;
class SaveFileManager;
class SearchSet;
@ -1436,44 +1437,12 @@ public:
* use dummy implementations for these methods.
*/
typedef struct OpaqueMutex *MutexRef;
/**
* Create a new mutex.
*
* @return The newly created mutex, or 0 if an error occurred.
*/
virtual MutexRef createMutex() = 0;
/**
* Lock the given mutex.
*
* @note ScummVM code assumes that the mutex implementation supports
* recursive locking. That is, a thread can lock a mutex twice without
* deadlocking. In case of a multilock, the mutex must be unlocked
* as many times as it was locked befored it really becomes unlocked.
*
* @param mutex The mutex to lock.
*/
virtual void lockMutex(MutexRef mutex) = 0;
/**
* Unlock the given mutex.
*
* @param mutex The mutex to unlock.
*/
virtual void unlockMutex(MutexRef mutex) = 0;
/**
* Delete the given mutex.
*
* Make sure the mutex is unlocked before you delete it.
* If you delete a locked mutex, the behavior is undefined.
* In particular, your program may crash.
*
* @param mutex The mutex to delete.
*/
virtual void deleteMutex(MutexRef mutex) = 0;
virtual Common::MutexInternal *createMutex() = 0;
/** @} */