[+] RuntimeWaitForSecondaryTick()
This commit is contained in:
parent
e7d8e5b010
commit
98d79a5aa3
@ -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();
|
||||||
}
|
}
|
@ -233,6 +233,11 @@ namespace Aurora
|
|||||||
Pump();
|
Pump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUKN_SYM void RuntimeWaitForSecondaryTick()
|
||||||
|
{
|
||||||
|
Grug::WaitForGrugTick();
|
||||||
|
}
|
||||||
|
|
||||||
void RuntimeLateClean()
|
void RuntimeLateClean()
|
||||||
{
|
{
|
||||||
::RuntimeLateClean();
|
::RuntimeLateClean();
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
@ -25,4 +25,5 @@ namespace Aurora::Grug
|
|||||||
void DeinitGrug();
|
void DeinitGrug();
|
||||||
|
|
||||||
void CloseHandle(AuUInt64 handle);
|
void CloseHandle(AuUInt64 handle);
|
||||||
|
void WaitForGrugTick();
|
||||||
}
|
}
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user