[+] 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
* (primarily legacy command dispatch)
* @deprecated
* @return
*/
AUKN_SYM void RuntimeSysPump();
AUKN_SYM void RuntimeWaitForSecondaryTick();
}

View File

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

View File

@ -30,12 +30,13 @@ namespace Aurora::Grug
static const auto kGrugSleepMs = 100;
static const auto kGrugFlushMs = 500;
static AuThreads::ThreadUnique_t gGrugsBigWorld;
static AuCondMutex gMutex; // ^ that
static AuConditionVariable gCondVar(AuUnsafeRaiiToShared(gMutex.AsPointer())); // slow logger work queue
static AuSemaphore gArrows;
static AuMutex gOtherMutex;
static AuList<AuUInt> gHandlesToClose;
static AuThreads::ThreadUnique_t gGrugsBigWorld;
static AuCondMutex gMutex; // ^ that
static AuConditionVariable gCondVar(AuUnsafeRaiiToShared(gMutex.AsPointer())); // slow logger work queue
static AuSemaphore gArrows;
static AuMutex gOtherMutex;
static AuList<AuUInt> gHandlesToClose;
static AuList<AuThreadPrimitives::IEvent *> gEventsToTrigger;
static void SlowStartupTasks()
{
@ -194,13 +195,22 @@ namespace Aurora::Grug
void GrugDoIoWork()
{
if (gHandlesToClose.empty())
decltype(gHandlesToClose) toClose;
decltype(gEventsToTrigger) toTrigger;
if (gHandlesToClose.empty() &&
gEventsToTrigger.empty())
{
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)
auto pHandle = (void *)uHandle;
@ -209,6 +219,11 @@ namespace Aurora::Grug
close(uHandle);
#endif
}
for (const auto pEvent : toTrigger)
{
pEvent->Set();
}
}
void GrugFlushFlushs()
@ -229,4 +244,27 @@ namespace Aurora::Grug
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 CloseHandle(AuUInt64 handle);
void WaitForGrugTick();
}

View File

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

View File

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