Merge pull request #8628 from unknownbrackets/ui-minor

Cleanup in UI, remove dup mutex define, wait for gameinfo items
This commit is contained in:
Henrik Rydgård 2016-03-06 23:59:33 +01:00
commit 6f30401800
24 changed files with 134 additions and 444 deletions

View File

@ -233,7 +233,6 @@
<ClInclude Include="MipsEmitter.h" />
<ClInclude Include="MsgHandler.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StdMutex.h" />
<ClInclude Include="StringUtils.h" />
<ClInclude Include="Swap.h" />
<ClInclude Include="ThreadPools.h" />

View File

@ -19,7 +19,6 @@
<ClInclude Include="MemArena.h" />
<ClInclude Include="MemoryUtil.h" />
<ClInclude Include="MsgHandler.h" />
<ClInclude Include="StdMutex.h" />
<ClInclude Include="StringUtils.h" />
<ClInclude Include="Thunk.h" />
<ClInclude Include="Timer.h" />

View File

@ -187,7 +187,7 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const
if (level > log->GetLevel() || !log->IsEnabled() || !log->HasListeners())
return;
std::lock_guard<std::mutex> lk(log_lock_);
lock_guard lk(log_lock_);
static const char level_to_char[8] = "-NEWIDV";
char formattedTime[13];
Common::Timer::GetTimeFormatted(formattedTime);
@ -266,13 +266,13 @@ LogChannel::LogChannel(const char* shortName, const char* fullName, bool enable)
// LogContainer
void LogChannel::AddListener(LogListener *listener) {
std::lock_guard<std::mutex> lk(m_listeners_lock);
lock_guard lk(m_listeners_lock);
m_listeners.insert(listener);
m_hasListeners = true;
}
void LogChannel::RemoveListener(LogListener *listener) {
std::lock_guard<std::mutex> lk(m_listeners_lock);
lock_guard lk(m_listeners_lock);
m_listeners.erase(listener);
m_hasListeners = !m_listeners.empty();
}
@ -281,7 +281,7 @@ void LogChannel::Trigger(LogTypes::LOG_LEVELS level, const char *msg) {
#ifdef __SYMBIAN32__
RDebug::Printf("%s",msg);
#else
std::lock_guard<std::mutex> lk(m_listeners_lock);
lock_guard lk(m_listeners_lock);
std::set<LogListener*>::const_iterator i;
for (i = m_listeners.begin(); i != m_listeners.end(); ++i) {
@ -303,7 +303,7 @@ void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) {
if (!IsEnabled() || !IsValid())
return;
std::lock_guard<std::mutex> lk(m_log_lock);
lock_guard lk(m_log_lock);
m_logfile << msg << std::flush;
}

View File

@ -17,13 +17,12 @@
#pragma once
#include <set>
#include "base/mutex.h"
#include "file/ini_file.h"
#include "Log.h"
#include "StringUtils.h"
#include "FileUtil.h"
#include "file/ini_file.h"
#include <set>
#include "StdMutex.h"
#define MAX_MESSAGES 8000
#define MAX_MSGLEN 1024
@ -51,7 +50,7 @@ public:
const char* GetName() const { return "file"; }
private:
std::mutex m_log_lock;
recursive_mutex m_log_lock;
std::ofstream m_logfile;
bool m_enable;
};
@ -113,7 +112,7 @@ public:
private:
char m_fullName[128];
char m_shortName[32];
std::mutex m_listeners_lock;
recursive_mutex m_listeners_lock;
std::set<LogListener*> m_listeners;
bool m_hasListeners;
};
@ -128,7 +127,7 @@ private:
DebuggerLogListener *debuggerLog_;
RingbufferLogListener *ringLog_;
static LogManager *logManager_; // Singleton. Ugh.
std::mutex log_lock_;
recursive_mutex log_lock_;
LogManager();
~LogManager();

View File

@ -1,353 +0,0 @@
#pragma once
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
// Note: __MAC_10_7 is defined on 10.7+.
#if (__cplusplus >= 201103L || defined(__APPLE__) \
|| (GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__)) \
/* GCC 4.4 provides <mutex>, except on these platforms: */ \
&& !defined(ANDROID) && !defined(__SYMBIAN32__) && !defined(MACGNUSTD)
#include <mutex>
#else
// partial <mutex> implementation for win32/pthread
#include <algorithm>
#if defined(_WIN32) // WIN32
#include "CommonWindows.h"
#else // POSIX
#include <pthread.h>
#endif
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
#define USE_RVALUE_REFERENCES
#endif
#if defined(_WIN32) && defined(_M_X64)
#define USE_SRWLOCKS
#endif
namespace std
{
class recursive_mutex
{
#ifdef _WIN32
typedef CRITICAL_SECTION native_type;
#else
typedef pthread_mutex_t native_type;
#endif
public:
typedef native_type* native_handle_type;
recursive_mutex(const recursive_mutex&) /*= delete*/;
recursive_mutex& operator=(const recursive_mutex&) /*= delete*/;
recursive_mutex()
{
#ifdef _WIN32
InitializeCriticalSection(&m_handle);
#else
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_handle, &attr);
#endif
}
~recursive_mutex()
{
#ifdef _WIN32
DeleteCriticalSection(&m_handle);
#else
pthread_mutex_destroy(&m_handle);
#endif
}
void lock()
{
#ifdef _WIN32
EnterCriticalSection(&m_handle);
#else
pthread_mutex_lock(&m_handle);
#endif
}
void unlock()
{
#ifdef _WIN32
LeaveCriticalSection(&m_handle);
#else
pthread_mutex_unlock(&m_handle);
#endif
}
bool try_lock()
{
#ifdef _WIN32
return (0 != TryEnterCriticalSection(&m_handle));
#else
return !pthread_mutex_trylock(&m_handle);
#endif
}
native_handle_type native_handle()
{
return &m_handle;
}
private:
native_type m_handle;
};
#if !defined(_WIN32) || defined(USE_SRWLOCKS)
class mutex
{
#ifdef _WIN32
typedef SRWLOCK native_type;
#else
typedef pthread_mutex_t native_type;
#endif
public:
typedef native_type* native_handle_type;
mutex(const mutex&) /*= delete*/;
mutex& operator=(const mutex&) /*= delete*/;
mutex()
{
#ifdef _WIN32
InitializeSRWLock(&m_handle);
#else
pthread_mutex_init(&m_handle, NULL);
#endif
}
~mutex()
{
#ifdef _WIN32
#else
pthread_mutex_destroy(&m_handle);
#endif
}
void lock()
{
#ifdef _WIN32
AcquireSRWLockExclusive(&m_handle);
#else
pthread_mutex_lock(&m_handle);
#endif
}
void unlock()
{
#ifdef _WIN32
ReleaseSRWLockExclusive(&m_handle);
#else
pthread_mutex_unlock(&m_handle);
#endif
}
bool try_lock()
{
#ifdef _WIN32
// XXX TryAcquireSRWLockExclusive requires Windows 7!
// return (0 != TryAcquireSRWLockExclusive(&m_handle));
return false;
#else
return !pthread_mutex_trylock(&m_handle);
#endif
}
native_handle_type native_handle()
{
return &m_handle;
}
private:
native_type m_handle;
};
#else
typedef recursive_mutex mutex; // just use CriticalSections
#endif
enum defer_lock_t { defer_lock };
enum try_to_lock_t { try_to_lock };
enum adopt_lock_t { adopt_lock };
template <class Mutex>
class lock_guard
{
public:
typedef Mutex mutex_type;
explicit lock_guard(mutex_type& m)
: pm(m)
{
m.lock();
}
lock_guard(mutex_type& m, adopt_lock_t)
: pm(m)
{
}
~lock_guard()
{
pm.unlock();
}
lock_guard(lock_guard const&) /*= delete*/;
lock_guard& operator=(lock_guard const&) /*= delete*/;
private:
mutex_type& pm;
};
template <class Mutex>
class unique_lock
{
public:
typedef Mutex mutex_type;
unique_lock()
: pm(NULL), owns(false)
{}
/*explicit*/ unique_lock(mutex_type& m)
: pm(&m), owns(true)
{
m.lock();
}
unique_lock(mutex_type& m, defer_lock_t)
: pm(&m), owns(false)
{}
unique_lock(mutex_type& m, try_to_lock_t)
: pm(&m), owns(m.try_lock())
{}
unique_lock(mutex_type& m, adopt_lock_t)
: pm(&m), owns(true)
{}
//template <class Clock, class Duration>
//unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
//template <class Rep, class Period>
//unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
~unique_lock()
{
if (owns_lock())
mutex()->unlock();
}
#ifdef USE_RVALUE_REFERENCES
unique_lock& operator=(const unique_lock&) /*= delete*/;
unique_lock& operator=(unique_lock&& other)
{
#else
unique_lock& operator=(const unique_lock& u)
{
// ugly const_cast to get around lack of rvalue references
unique_lock& other = const_cast<unique_lock&>(u);
#endif
swap(other);
return *this;
}
#ifdef USE_RVALUE_REFERENCES
unique_lock(const unique_lock&) /*= delete*/;
unique_lock(unique_lock&& other)
: pm(NULL), owns(false)
{
#else
unique_lock(const unique_lock& u)
: pm(NULL), owns(false)
{
// ugly const_cast to get around lack of rvalue references
unique_lock& other = const_cast<unique_lock&>(u);
#endif
swap(other);
}
void lock()
{
mutex()->lock();
owns = true;
}
bool try_lock()
{
owns = mutex()->try_lock();
return owns;
}
//template <class Rep, class Period>
//bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
//template <class Clock, class Duration>
//bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock()
{
mutex()->unlock();
owns = false;
}
void swap(unique_lock& u)
{
std::swap(pm, u.pm);
std::swap(owns, u.owns);
}
mutex_type* release()
{
mutex_type* const ret = mutex();
pm = NULL;
owns = false;
return ret;
}
bool owns_lock() const
{
return owns;
}
//explicit operator bool () const
//{
// return owns_lock();
//}
mutex_type* mutex() const
{
return pm;
}
private:
mutex_type* pm;
bool owns;
};
template <class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y)
{
x.swap(y);
}
}
#endif

View File

@ -20,10 +20,10 @@
#include <cstdio>
#include "base/logging.h"
#include "base/mutex.h"
#include "profiler/profiler.h"
#include "Common/MsgHandler.h"
#include "Common/StdMutex.h"
#include "Common/Atomics.h"
#include "Core/CoreTiming.h"
#include "Core/Core.h"
@ -86,7 +86,7 @@ s64 idledCycles;
s64 lastGlobalTimeTicks;
s64 lastGlobalTimeUs;
static std::recursive_mutex externalEventSection;
static recursive_mutex externalEventSection;
// Warning: not included in save state.
void (*advanceCallback)(int cyclesExecuted) = NULL;
@ -228,7 +228,7 @@ void Shutdown()
delete ev;
}
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
while(eventTsPool)
{
Event *ev = eventTsPool;
@ -252,7 +252,7 @@ u64 GetIdleTicks()
// schedule things to be executed on the main thread.
void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata)
{
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
Event *ne = GetNewTsEvent();
ne->time = GetTicks() + cyclesIntoFuture;
ne->type = event_type;
@ -273,7 +273,7 @@ void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata)
{
if(false) //Core::IsCPUThread())
{
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
event_types[event_type].callback(userdata, 0);
}
else
@ -368,7 +368,7 @@ s64 UnscheduleEvent(int event_type, u64 userdata)
s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata)
{
s64 result = 0;
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
if (!tsFirst)
return result;
while(tsFirst)
@ -478,7 +478,7 @@ void RemoveEvent(int event_type)
void RemoveThreadsafeEvent(int event_type)
{
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
if (!tsFirst)
{
return;
@ -552,7 +552,7 @@ void MoveEvents()
{
Common::AtomicStoreRelease(hasTsEvents, 0);
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
// Move events from async queue into main queue
while (tsFirst)
{
@ -692,7 +692,7 @@ void Event_DoStateOld(PointerWrap &p, BaseEvent *ev)
void DoState(PointerWrap &p)
{
std::lock_guard<std::recursive_mutex> lk(externalEventSection);
lock_guard lk(externalEventSection);
auto s = p.Section("CoreTiming", 1, 3);
if (!s)

View File

@ -17,6 +17,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <math.h>
#include "base/mutex.h"
#include "Globals.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
@ -24,7 +25,6 @@
#include "Core/CoreTiming.h"
#include "Core/MemMapHelpers.h"
#include "Common/ChunkFile.h"
#include "Common/StdMutex.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/HLE/sceDisplay.h"
#include "Core/HLE/sceKernel.h"
@ -84,7 +84,7 @@ static int ctrlIdleBack = -1;
static int ctrlCycle = 0;
static std::vector<SceUID> waitingThreads;
static std::recursive_mutex ctrlMutex;
static recursive_mutex ctrlMutex;
static int ctrlTimer = -1;
@ -101,7 +101,7 @@ const u32 CTRL_EMU_RAPIDFIRE_MASK = CTRL_UP | CTRL_DOWN | CTRL_LEFT | CTRL_RIGHT
static void __CtrlUpdateLatch()
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
// Copy in the current data to the current buffer.
ctrlBufs[ctrlBuf] = ctrlCurrent;
@ -144,14 +144,14 @@ static int __CtrlResetLatch()
u32 __CtrlPeekButtons()
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
return ctrlCurrent.buttons;
}
void __CtrlPeekAnalog(int stick, float *x, float *y)
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
*x = (ctrlCurrent.analog[stick][CTRL_ANALOG_X] - 127.5f) / 127.5f;
*y = -(ctrlCurrent.analog[stick][CTRL_ANALOG_Y] - 127.5f) / 127.5f;
@ -170,27 +170,27 @@ u32 __CtrlReadLatch()
void __CtrlButtonDown(u32 buttonBit)
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
ctrlCurrent.buttons |= buttonBit;
}
void __CtrlButtonUp(u32 buttonBit)
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
ctrlCurrent.buttons &= ~buttonBit;
}
void __CtrlSetAnalogX(float x, int stick)
{
u8 scaled = clamp_u8((int)ceilf(x * 127.5f + 127.5f));
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
ctrlCurrent.analog[stick][CTRL_ANALOG_X] = scaled;
}
void __CtrlSetAnalogY(float y, int stick)
{
u8 scaled = clamp_u8((int)ceilf(-y * 127.5f + 127.5f));
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
ctrlCurrent.analog[stick][CTRL_ANALOG_Y] = scaled;
}
@ -304,7 +304,7 @@ void __CtrlInit()
ctrlIdleBack = -1;
ctrlCycle = 0;
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
ctrlBuf = 1;
ctrlBufRead = 0;
@ -326,7 +326,7 @@ void __CtrlInit()
void __CtrlDoState(PointerWrap &p)
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
lock_guard guard(ctrlMutex);
auto s = p.Section("sceCtrl", 1, 3);
if (!s)

View File

@ -15,13 +15,14 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include <vector>
#include "base/mutex.h"
#include "base/timeutil.h"
#include "base/NativeApp.h"
#include "i18n/i18n.h"
#include "Common/StdMutex.h"
#include "Common/FileUtil.h"
#include "Common/ChunkFile.h"
@ -206,7 +207,7 @@ namespace SaveState
static bool needsProcess = false;
static std::vector<Operation> pending;
static std::recursive_mutex mutex;
static recursive_mutex mutex;
static bool hasLoadedState = false;
// TODO: Should this be configurable?
@ -250,7 +251,7 @@ namespace SaveState
void Enqueue(SaveState::Operation op)
{
std::lock_guard<std::recursive_mutex> guard(mutex);
lock_guard guard(mutex);
pending.push_back(op);
// Don't actually run it until next frame.
@ -486,7 +487,7 @@ namespace SaveState
std::vector<Operation> Flush()
{
std::lock_guard<std::recursive_mutex> guard(mutex);
lock_guard guard(mutex);
std::vector<Operation> copy = pending;
pending.clear();
@ -670,7 +671,7 @@ namespace SaveState
// Make sure there's a directory for save slots
pspFileSystem.MkDir("ms0:/PSP/PPSSPP_STATE");
std::lock_guard<std::recursive_mutex> guard(mutex);
lock_guard guard(mutex);
rewindStates.Clear();
hasLoadedState = false;

View File

@ -15,18 +15,20 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <deque>
#include "input/input_state.h"
#include "ui/ui.h"
#include "util/text/utf8.h"
#include "i18n/i18n.h"
#include "Common/FileUtil.h"
#include "Core/Core.h"
#include "Core/Config.h"
#include "Core/CwCheat.h"
#include "Core/MIPS/JitCommon/NativeJit.h"
#include "UI/OnScreenDisplay.h"
#include "UI/ui_atlas.h"
#include "UI/GamepadEmu.h"
#include "UI/MainScreen.h"
#include "UI/EmuScreen.h"

View File

@ -15,16 +15,11 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <deque>
#include "Common/FileUtil.h"
#include "base/functional.h"
#include "ui/view.h"
#include "ui/ui_screen.h"
#include "ui/ui_context.h"
#include "../Core/CwCheat.h"
#include "UI/MiscScreens.h"
#include "UI/GameSettingsScreen.h"
extern std::string activeCheatFile;
extern std::string gameTitle;
@ -37,7 +32,6 @@ public:
void processFileOff(std::string deactivatedCheat);
const char * name;
std::string activatedCheat, deactivatedCheat;
UI::EventReturn OnBack(UI::EventParams &params);
UI::EventReturn OnAddCheat(UI::EventParams &params);
UI::EventReturn OnImportCheat(UI::EventParams &params);
UI::EventReturn OnEditCheatFile(UI::EventParams &params);

View File

@ -298,6 +298,16 @@ std::string GameInfo::GetTitle() {
return title;
}
bool GameInfo::IsPending() {
lock_guard guard(lock);
return pending;
}
bool GameInfo::IsWorking() {
lock_guard guard(lock);
return working;
}
void GameInfo::SetTitle(const std::string &newTitle) {
lock_guard guard(lock);
title = newTitle;
@ -355,6 +365,7 @@ public:
std::string filename = gamePath_;
{
lock_guard lock(info_->lock);
info_->working = true;
info_->fileType = Identify_File(info_->GetFileLoader());
}
@ -581,8 +592,12 @@ handleELF:
info_->saveDataSize = info_->GetSaveDataSizeInBytes();
info_->installDataSize = info_->GetInstallDataSizeInBytes();
}
info_->pending = false;
info_->DisposeFileLoader();
lock_guard lock(info_->lock);
info_->pending = false;
info_->working = false;
// ILOG("Completed writing info for %s", info_->GetTitle().c_str());
}
@ -702,6 +717,18 @@ void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
}
}
void GameInfoCache::WaitUntilDone(GameInfo *info) {
while (info->IsPending()) {
if (gameInfoWQ_->WaitUntilDone(false)) {
// A true return means everything finished, so bail out.
// This way even if something gets stuck, we won't hang.
break;
}
// Otherwise, wait again if it's not done...
}
}
// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
@ -735,15 +762,21 @@ again:
if (!info) {
info = new GameInfo();
}
{
lock_guard lock(info->lock);
if (info->IsWorking()) {
// Uh oh, it's currently in process. It could mark pending = false with the wrong wantFlags.
// Let's wait it out, then queue.
WaitUntilDone(info);
}
info->wantFlags |= wantFlags;
info->pending = true;
}
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info);
gameInfoWQ_->Add(item);
info->pending = true;
info_[gamePath] = info;
return info;
}

View File

@ -22,12 +22,12 @@
#include "base/mutex.h"
#include "file/file_util.h"
#include "thread/prioritizedworkqueue.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/Loaders.h"
class Thin3DContext;
class Thin3DTexture;
class PrioritizedWorkQueue;
// A GameInfo holds information about a game, and also lets you do things that the VSH
// does on the PSP, namely checking for and deleting savedata, and similar things.
@ -98,7 +98,7 @@ public:
: disc_total(0), disc_number(0), region(-1), fileType(FILETYPE_UNKNOWN), paramSFOLoaded(false),
hasConfig(false), iconTexture(nullptr), pic0Texture(nullptr), pic1Texture(nullptr), wantFlags(0),
lastAccessedTime(0.0), timeIconWasLoaded(0.0), timePic0WasLoaded(0.0), timePic1WasLoaded(0.0),
gameSize(0), saveDataSize(0), installDataSize(0), pending(true), fileLoader(nullptr) {}
gameSize(0), saveDataSize(0), installDataSize(0), pending(true), working(false), fileLoader(nullptr) {}
~GameInfo();
bool Delete(); // Better be sure what you're doing when calling this.
@ -119,6 +119,9 @@ public:
std::string GetTitle();
void SetTitle(const std::string &newTitle);
bool IsPending();
bool IsWorking();
// Hold this when reading or writing from the GameInfo.
// Don't need to hold it when just passing around the pointer,
// and obviously also not when creating it and holding the only pointer
@ -164,6 +167,7 @@ public:
u64 saveDataSize;
u64 installDataSize;
bool pending;
bool working;
protected:
// Note: this can change while loading, use GetTitle().
@ -180,7 +184,6 @@ public:
// This creates a background worker thread!
void Clear();
void ClearTextures();
void PurgeType(IdentifiedFileType fileType);
// All data in GameInfo including iconTexture may be zero the first time you call this
@ -192,10 +195,7 @@ public:
PrioritizedWorkQueue *WorkQueue() { return gameInfoWQ_; }
void WaitUntilDone(GameInfo *info) {
// Hack - should really wait specifically for that item.
gameInfoWQ_->WaitUntilDone();
}
void WaitUntilDone(GameInfo *info);
private:
void Init();

View File

@ -100,7 +100,6 @@ private:
UI::EventReturn OnImmersiveModeChange(UI::EventParams &e);
UI::EventReturn OnAdhocGuides(UI::EventParams &e);
UI::EventReturn OnAudioBackend(UI::EventParams &e);
UI::EventReturn OnSavedataManager(UI::EventParams &e);
UI::EventReturn OnSysInfo(UI::EventParams &e);
@ -145,7 +144,6 @@ protected:
private:
std::string tempProAdhocServer;
UI::TextView *addrView_;
UI::EventReturn OnBack(UI::EventParams &e);
UI::EventReturn On0Click(UI::EventParams &e);
UI::EventReturn On1Click(UI::EventParams &e);
UI::EventReturn On2Click(UI::EventParams &e);

View File

@ -27,7 +27,9 @@
#include "ui/view.h"
#include "ui/viewgroup.h"
#include "ui/ui.h"
#include "util/random/rng.h"
#include "file/vfs.h"
#include "UI/ui_atlas.h"
#include "UI/MiscScreens.h"
#include "UI/EmuScreen.h"
#include "UI/MainScreen.h"
@ -35,12 +37,11 @@
#include "Core/Config.h"
#include "Core/Host.h"
#include "Core/System.h"
#include "Core/MIPS/JitCommon/JitCommon.h"
#include "Core/MIPS/JitCommon/NativeJit.h"
#include "Core/HLE/sceUtility.h"
#include "Common/CPUDetect.h"
#include "Common/FileUtil.h"
#include "GPU/GPUState.h"
#include "GPU/Common/PostShader.h"
#include "ui_atlas.h"
@ -48,13 +49,6 @@
#pragma execution_character_set("utf-8")
#endif
#include "base/timeutil.h"
#include "base/colorutil.h"
#include "gfx_es2/draw_buffer.h"
#include "util/random/rng.h"
#include "UI/ui_atlas.h"
static const int symbols[4] = {
I_CROSS,
I_CIRCLE,

View File

@ -24,7 +24,8 @@
#include "file/file_util.h"
#include "base/functional.h"
#include "ui/ui_screen.h"
#include "GPU/Common/PostShader.h"
struct ShaderInfo;
extern std::string boot_filename;

View File

@ -55,7 +55,7 @@ restart:
void OnScreenMessages::Show(const std::string &text, float duration_s, uint32_t color, int icon, bool checkUnique, const char *id) {
double now = time_now_d();
std::lock_guard<std::recursive_mutex> guard(mutex_);
lock_guard guard(mutex_);
if (checkUnique) {
for (auto iter = messages_.begin(); iter != messages_.end(); ++iter) {
if (iter->text == text || (id && iter->id && !strcmp(iter->id, id))) {

View File

@ -3,9 +3,9 @@
#include <string>
#include <list>
#include "base/mutex.h"
#include "base/basictypes.h"
#include "math/geom2d.h"
#include "Common/StdMutex.h"
#include "ui/view.h"
@ -39,7 +39,7 @@ public:
private:
std::list<Message> messages_;
std::recursive_mutex mutex_;
recursive_mutex mutex_;
};
class OnScreenMessagesView : public UI::InertView {

View File

@ -16,8 +16,10 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "i18n/i18n.h"
#include "gfx_es2/draw_buffer.h"
#include "ui/view.h"
#include "ui/viewgroup.h"
#include "ui/ui_context.h"
#include "ui/ui_screen.h"
#include "thin3d/thin3d.h"
@ -40,9 +42,6 @@
#include "UI/MainScreen.h"
#include "UI/GameInfoCache.h"
#include "gfx_es2/draw_buffer.h"
#include "ui/ui_context.h"
void AsyncImageFileView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
if (texture_) {
float texw = (float)texture_->Width();

View File

@ -29,6 +29,7 @@
#include "Common/StringUtils.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "Core/Util/GameManager.h"
#include "UI/EmuScreen.h"
#include "UI/Store.h"

View File

@ -22,7 +22,6 @@
#include "ui/viewgroup.h"
#include "net/http_client.h"
#include "Core/Util/GameManager.h"
#include "UI/MiscScreens.h"
// Game screen: Allows you to start a game, delete saves, delete the game,
@ -68,7 +67,6 @@ public:
protected:
virtual void CreateViews();
UI::EventReturn OnGameSelected(UI::EventParams &e);
UI::EventReturn OnCategorySelected(UI::EventParams &e);
UI::EventReturn OnRetry(UI::EventParams &e);
UI::EventReturn OnGameLaunch(UI::EventParams &e);

View File

@ -19,6 +19,7 @@
#include "base/NativeApp.h"
#include "base/logging.h"
#include "base/timeutil.h"
#include "thread/prioritizedworkqueue.h"
#include "thread/threadutil.h"
#include "file/zip_read.h"
#include "input/input_state.h"

View File

@ -19,6 +19,8 @@
#undef p
#undef DrawText
#undef itoa
#undef min
#undef max
#else
#include <pthread.h>

View File

@ -33,28 +33,45 @@ void PrioritizedWorkQueue::Flush() {
ILOG("Flushed %d un-executed tasks", flush_count);
}
void PrioritizedWorkQueue::WaitUntilDone() {
if (queue_.empty())
return;
// This could be made more elegant..
while (true) {
bool empty;
{
lock_guard guard(mutex_);
empty = queue_.empty() && !working_;
}
if (empty) {
break;
}
sleep_ms(10);
bool PrioritizedWorkQueue::WaitUntilDone(bool all) {
// We'll lock drain this entire time, so make sure you follow that lock ordering.
lock_guard guard(drainMutex_);
if (AllItemsDone()) {
return true;
}
while (!AllItemsDone()) {
drain_.wait(drainMutex_);
if (!all) {
// Return whether empty or not, something just drained.
return AllItemsDone();
}
}
return true;
}
void PrioritizedWorkQueue::NotifyDrain() {
lock_guard guard(drainMutex_);
drain_.notify_one();
}
bool PrioritizedWorkQueue::AllItemsDone() {
lock_guard guard(mutex_);
return queue_.empty() && !working_;
}
// The worker should simply call this in a loop. Will block when appropriate.
PrioritizedWorkQueueItem *PrioritizedWorkQueue::Pop() {
{
lock_guard guard(mutex_);
working_ = false; // The thread only calls Pop if it's done.
}
// Important: make sure mutex_ is not locked while draining.
NotifyDrain();
lock_guard guard(mutex_);
working_ = false; // The thread only calls Pop if it's done.
if (done_) {
return 0;
}

View File

@ -34,17 +34,22 @@ public:
void Flush();
bool Done() { return done_; }
void Stop();
void WaitUntilDone();
bool WaitUntilDone(bool all = true);
bool IsWorking() {
return working_;
}
private:
void NotifyDrain();
bool AllItemsDone();
bool done_;
bool working_;
recursive_mutex mutex_;
recursive_mutex drainMutex_;
condition_variable notEmpty_;
condition_variable drain_;
std::vector<PrioritizedWorkQueueItem *> queue_;