Handle OpenFile() errors in a more threadsafe way.

Probably needs better cleanup though.
This commit is contained in:
Unknown W. Brackets 2013-08-10 09:54:14 -07:00
parent b5ac31bbea
commit 333cc33efb
3 changed files with 22 additions and 14 deletions

View File

@ -172,7 +172,6 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle)
return 0;
}
extern u32 ioErrorCode;
bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system)
{
lock_guard guard(lock);
@ -195,7 +194,7 @@ bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpat
//Attempt to emulate SCE_KERNEL_ERROR_NOCWD / 8002032C: may break things requiring fixes elsewhere
if (inpath.find(':') == std::string::npos /* means path is relative */)
{
ioErrorCode = SCE_KERNEL_ERROR_NOCWD;
lastOpenError = SCE_KERNEL_ERROR_NOCWD;
WARN_LOG_REPORT(HLE, "Path is relative, but current directory not set for thread %i. returning 8002032C(SCE_KERNEL_ERROR_NOCWD) instead.", currentThread);
}
}
@ -256,9 +255,18 @@ void MetaFileSystem::Shutdown()
startingDirectory = "";
}
u32 MetaFileSystem::OpenWithError(int &error, std::string filename, FileAccess access, const char *devicename)
{
lock_guard guard(lock);
u32 h = OpenFile(filename, access, devicename);
error = lastOpenError;
return h;
}
u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename)
{
lock_guard guard(lock);
lastOpenError = 0;
std::string of;
MountPoint *mount;
if (MapFilePath(filename, of, &mount))

View File

@ -35,6 +35,7 @@ private:
currentDir_t currentDir;
std::string startingDirectory;
int lastOpenError;
recursive_mutex lock;
public:
@ -74,7 +75,8 @@ public:
bool GetHostPath(const std::string &inpath, std::string &outpath);
std::vector<PSPFileInfo> GetDirListing(std::string path);
u32 OpenFile(std::string filename, FileAccess access, const char *devicename=NULL);
u32 OpenFile(std::string filename, FileAccess access, const char *devicename = NULL);
u32 OpenWithError(int &error, std::string filename, FileAccess access, const char *devicename = NULL);
void CloseFile(u32 handle);
size_t ReadFile(u32 handle, u8 *pointer, s64 size);
size_t WriteFile(u32 handle, const u8 *pointer, s64 size);

View File

@ -103,8 +103,6 @@ const int PSP_MIN_FD = 4;
static int asyncNotifyEvent = -1;
static SceUID fds[PSP_COUNT_FDS];
u32 ioErrorCode = 0;
#define SCE_STM_FDIR 0x1000
#define SCE_STM_FREG 0x2000
#define SCE_STM_FLNK 0x4000
@ -782,7 +780,7 @@ u32 sceIoLseek32Async(int id, int offset, int whence) {
return 0;
}
FileNode *__IoOpen(const char* filename, int flags, int mode) {
FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) {
//memory stick filename
int access = FILEACCESS_NONE;
if (flags & O_RDONLY)
@ -796,9 +794,7 @@ FileNode *__IoOpen(const char* filename, int flags, int mode) {
PSPFileInfo info = pspFileSystem.GetFileInfo(filename);
ioErrorCode = 0;
u32 h = pspFileSystem.OpenFile(filename, (FileAccess) access);
u32 h = pspFileSystem.OpenWithError(error, filename, (FileAccess) access);
if (h == 0) {
return NULL;
}
@ -821,11 +817,12 @@ u32 sceIoOpen(const char* filename, int flags, int mode) {
if (!__KernelIsDispatchEnabled())
return -1;
FileNode *f = __IoOpen(filename, flags, mode);
int error;
FileNode *f = __IoOpen(error, filename, flags, mode);
if (f == NULL)
{
//Timing is not accurate, aiming low for now.
if (ioErrorCode == SCE_KERNEL_ERROR_NOCWD)
// Timing is not accurate, aiming low for now.
if (error == SCE_KERNEL_ERROR_NOCWD)
{
ERROR_LOG(HLE, "SCE_KERNEL_ERROR_NOCWD=sceIoOpen(%s, %08x, %08x) - no current working directory", filename, flags, mode);
return hleDelayResult(SCE_KERNEL_ERROR_NOCWD , "no cwd", 10000);
@ -1294,7 +1291,8 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode)
if (!__KernelIsDispatchEnabled())
sceKernelResumeDispatchThread(1);
FileNode *f = __IoOpen(filename, flags, mode);
int error;
FileNode *f = __IoOpen(error, filename, flags, mode);
int fd;
// We have to return an fd here, which may have been destroyed when we reach Wait if it failed.
@ -1305,7 +1303,7 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode)
f = new FileNode();
f->handle = kernelObjects.Create(f);
f->fullpath = filename;
f->asyncResult = ERROR_ERRNO_FILE_NOT_FOUND;
f->asyncResult = error == 0 ? ERROR_ERRNO_FILE_NOT_FOUND : error;
f->closePending = true;
fd = __IoAllocFd(f);