[+] RuntimeWaitForSecondaryTick()

This commit is contained in:
Reece Wilson 2023-12-13 04:25:11 +00:00
parent e7d8e5b010
commit 98d79a5aa3
6 changed files with 217 additions and 127 deletions

View File

@ -113,7 +113,11 @@ namespace Aurora
/** /**
* @brief Single threaded main pump for GUI applications polling for non-async subsystem callbacks * @brief Single threaded main pump for GUI applications polling for non-async subsystem callbacks
* (primarily legacy command dispatch)
* @deprecated
* @return * @return
*/ */
AUKN_SYM void RuntimeSysPump(); AUKN_SYM void RuntimeSysPump();
AUKN_SYM void RuntimeWaitForSecondaryTick();
} }

View File

@ -233,6 +233,11 @@ namespace Aurora
Pump(); Pump();
} }
AUKN_SYM void RuntimeWaitForSecondaryTick()
{
Grug::WaitForGrugTick();
}
void RuntimeLateClean() void RuntimeLateClean()
{ {
::RuntimeLateClean(); ::RuntimeLateClean();

View File

@ -30,12 +30,13 @@ namespace Aurora::Grug
static const auto kGrugSleepMs = 100; static const auto kGrugSleepMs = 100;
static const auto kGrugFlushMs = 500; static const auto kGrugFlushMs = 500;
static AuThreads::ThreadUnique_t gGrugsBigWorld; static AuThreads::ThreadUnique_t gGrugsBigWorld;
static AuCondMutex gMutex; // ^ that static AuCondMutex gMutex; // ^ that
static AuConditionVariable gCondVar(AuUnsafeRaiiToShared(gMutex.AsPointer())); // slow logger work queue static AuConditionVariable gCondVar(AuUnsafeRaiiToShared(gMutex.AsPointer())); // slow logger work queue
static AuSemaphore gArrows; static AuSemaphore gArrows;
static AuMutex gOtherMutex; static AuMutex gOtherMutex;
static AuList<AuUInt> gHandlesToClose; static AuList<AuUInt> gHandlesToClose;
static AuList<AuThreadPrimitives::IEvent *> gEventsToTrigger;
static void SlowStartupTasks() static void SlowStartupTasks()
{ {
@ -194,13 +195,22 @@ namespace Aurora::Grug
void GrugDoIoWork() void GrugDoIoWork()
{ {
if (gHandlesToClose.empty()) decltype(gHandlesToClose) toClose;
decltype(gEventsToTrigger) toTrigger;
if (gHandlesToClose.empty() &&
gEventsToTrigger.empty())
{ {
return; return;
} }
AU_LOCK_GUARD(gOtherMutex); {
for (const auto uHandle : AuExchange(gHandlesToClose, {})) AU_LOCK_GUARD(gOtherMutex);
toClose = AuMove(gHandlesToClose);
toTrigger = AuMove(gEventsToTrigger);
}
for (const auto uHandle : toClose)
{ {
#if defined(AURORA_IS_MODERNNT_DERIVED) #if defined(AURORA_IS_MODERNNT_DERIVED)
auto pHandle = (void *)uHandle; auto pHandle = (void *)uHandle;
@ -209,6 +219,11 @@ namespace Aurora::Grug
close(uHandle); close(uHandle);
#endif #endif
} }
for (const auto pEvent : toTrigger)
{
pEvent->Set();
}
} }
void GrugFlushFlushs() void GrugFlushFlushs()
@ -229,4 +244,27 @@ namespace Aurora::Grug
NotifyGrugOfTelemetry(); NotifyGrugOfTelemetry();
} }
void WaitForGrugTick()
{
AuEvent event(false, true, true);
if (gGrugsBigWorld &&
gGrugsBigWorld.get() == AuThreads::GetThread())
{
return;
}
{
AU_DEBUG_MEMCRUNCH;
AU_LOCK_GUARD(gOtherMutex);
gEventsToTrigger.push_back(event.AsPointer());
}
{
NotifyGrugOfTelemetry();
}
event->Lock();
}
} }

View File

@ -25,4 +25,5 @@ namespace Aurora::Grug
void DeinitGrug(); void DeinitGrug();
void CloseHandle(AuUInt64 handle); void CloseHandle(AuUInt64 handle);
void WaitForGrugTick();
} }

View File

@ -158,144 +158,158 @@ namespace Aurora::IO
dwAttrs |= FILE_ATTRIBUTE_NORMAL; dwAttrs |= FILE_ATTRIBUTE_NORMAL;
} }
switch (create.eMode) for (AU_ITERATE_N(i, 2))
{ {
case FS::EFileOpenMode::eRead: switch (create.eMode)
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_READ,
dwShare,
false,
OPEN_EXISTING,
dwFlags,
dwAttrs);
if (hFileHandle != INVALID_HANDLE_VALUE)
{ {
this->uOSReadHandle = AuUInt64(hFileHandle); case FS::EFileOpenMode::eRead:
}
break;
}
case FS::EFileOpenMode::eReadWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{ {
hFileHandle = Win32Open(win32Path.c_str(), hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE, GENERIC_READ,
false,
false,
CREATE_NEW,
dwFlags,
dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_EXISTS ||
AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare, dwShare,
false, false,
OPEN_EXISTING, OPEN_EXISTING,
dwFlags, dwFlags,
dwAttrs); dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE) if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eReadWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE,
false,
false,
CREATE_NEW,
dwFlags,
dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_EXISTS ||
AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
{ {
hFileHandle = Win32Open(win32Path.c_str(), hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | GENERIC_READ | DELETE, GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare, dwShare,
false, false,
CREATE_NEW, OPEN_EXISTING,
dwFlags, dwFlags,
dwAttrs); dwAttrs);
}
}
if (hFileHandle != INVALID_HANDLE_VALUE) if (hFileHandle == INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | DELETE,
NULL,
false,
CREATE_NEW,
dwFlags,
dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_EXISTS ||
AuFS::FileExists(pathex.c_str()))
{ {
SysPushErrorResourceExists("File {} already exists", create.path); hFileHandle = Win32Open(win32Path.c_str(),
return false; GENERIC_WRITE | GENERIC_READ | DELETE,
dwShare,
false,
CREATE_NEW,
dwFlags,
dwAttrs);
} }
} }
}
else
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE,
dwShare,
false,
OPEN_EXISTING,
dwFlags,
dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE) if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSReadHandle = AuUInt64(hFileHandle);
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
case FS::EFileOpenMode::eWrite:
{
if (create.bAlwaysCreateDirTree)
{
FS::CreateDirectories(pathex, true);
}
if (create.bFailIfNonEmptyFile)
{ {
hFileHandle = Win32Open(win32Path.c_str(), hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | DELETE, GENERIC_WRITE | DELETE,
dwShare, NULL,
false, false,
CREATE_NEW, CREATE_NEW,
dwFlags, dwFlags,
dwAttrs); dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_EXISTS ||
AuFS::FileExists(pathex.c_str()))
{
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
}
}
else
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | FILE_READ_ATTRIBUTES | DELETE,
dwShare,
false,
OPEN_EXISTING,
dwFlags,
dwAttrs);
if (hFileHandle == INVALID_HANDLE_VALUE)
{
hFileHandle = Win32Open(win32Path.c_str(),
GENERIC_WRITE | DELETE,
dwShare,
false,
CREATE_NEW,
dwFlags,
dwAttrs);
}
}
if (hFileHandle != INVALID_HANDLE_VALUE)
{
this->uOSWriteHandle = AuUInt64(hFileHandle);
}
break;
}
}
if (hFileHandle == INVALID_HANDLE_VALUE)
{
if (i == 0)
{
RuntimeWaitForSecondaryTick();
}
else
{
SysPushErrorIO("Couldn't open: {}", create.path);
return false;
} }
} }
else
if (hFileHandle != INVALID_HANDLE_VALUE)
{ {
this->uOSWriteHandle = AuUInt64(hFileHandle); break;
} }
break;
}
}
if (hFileHandle == INVALID_HANDLE_VALUE)
{
SysPushErrorIO("Couldn't open: {}", create.path);
return false;
} }
this->bIsAsync = create.bAsyncHandle; this->bIsAsync = create.bAsyncHandle;

View File

@ -13,6 +13,8 @@
#include "FS/FileAdvisory.Unix.hpp" #include "FS/FileAdvisory.Unix.hpp"
#include "FS/FileStream.Unix.hpp" #include "FS/FileStream.Unix.hpp"
#include <Source/Grug/AuGrug.hpp>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -91,7 +93,11 @@ namespace Aurora::IO
return; return;
} }
#if 0
::close(fd); ::close(fd);
#else
Grug::CloseHandle(uOSHandle);
#endif
} }
void AFileHandle::InitStdIn(bool bSharing) void AFileHandle::InitStdIn(bool bSharing)
@ -183,30 +189,52 @@ namespace Aurora::IO
if (iFileDescriptor < 0) if (iFileDescriptor < 0)
{ {
if (errno == EEXIST) if (create.bFailIfNonEmptyFile)
{ {
SysPushErrorResourceExists("File {} already exists", create.path); if (errno == EEXIST)
return false; {
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
} }
if (errno == EISDIR) if (errno != EISDIR &&
errno != ENOENT)
{ {
flags &= ~(O_WRONLY | O_RDWR); RuntimeWaitForSecondaryTick();
iFileDescriptor = ::open(pathex.c_str(), iFileDescriptor = ::open(pathex.c_str(),
flags, flags,
0664); 0664);
} }
if (errno == ENFILE)
{
SysPushErrorIOResourceFailure("low resources");
return false;
}
if (iFileDescriptor < 0) if (iFileDescriptor < 0)
{ {
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno); if (errno == EEXIST)
return false; {
SysPushErrorResourceExists("File {} already exists", create.path);
return false;
}
if (errno == EISDIR)
{
flags &= ~(O_WRONLY | O_RDWR);
iFileDescriptor = ::open(pathex.c_str(),
flags,
0664);
}
if (iFileDescriptor < 0)
{
if (errno == ENFILE)
{
SysPushErrorIOResourceFailure("low resources");
return false;
}
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
return false;
}
} }
} }