[*] Begin resolving 8 months of Linux neglect
This commit is contained in:
parent
7100c807c8
commit
1f173a8799
@ -177,7 +177,7 @@ protected:
|
||||
|
||||
friend struct __detail::FutureAccessor;
|
||||
|
||||
CppFun<T>::B &GetValue()
|
||||
typename CppFun<T>::B &GetValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@ -316,7 +316,7 @@ private:
|
||||
this->pid = AuAsync::GetCurrentWorkerPId();
|
||||
}
|
||||
|
||||
CppFun<T>::B value;
|
||||
typename CppFun<T>::B value;
|
||||
ErrorStore_t errorValue;
|
||||
|
||||
AuThreadPrimitives::Mutex mutex;
|
||||
|
@ -35,6 +35,22 @@ namespace Aurora::Threading::Primitives
|
||||
static const auto kPrimitiveSize32NTCond = 20;
|
||||
static const auto kPrimitiveSize32NTCondMutex = 8;
|
||||
|
||||
static const auto kPrimitiveSize64LinuxMutex = 16;
|
||||
static const auto kPrimitiveSize64LinuxSemaphore = 16;
|
||||
static const auto kPrimitiveSize64LinuxCS = 128;
|
||||
static const auto kPrimitiveSize64LinuxEvent = 152;
|
||||
static const auto kPrimitiveSize64LinuxRWLock = 200;
|
||||
static const auto kPrimitiveSize64LinuxCond = 88;
|
||||
static const auto kPrimitiveSize64LinuxCondMutex = 48;
|
||||
|
||||
static const auto kPrimitiveSize32LinuxMutex = 8;
|
||||
static const auto kPrimitiveSize32LinuxSemaphore = 8;
|
||||
static const auto kPrimitiveSize32LinuxCS = 128;
|
||||
static const auto kPrimitiveSize32LinuxEvent = 152;
|
||||
static const auto kPrimitiveSize32LinuxRWLock = 200;
|
||||
static const auto kPrimitiveSize32LinuxCond = 88;
|
||||
static const auto kPrimitiveSize32LinuxCondMutex = 48;
|
||||
|
||||
// TODO: Other platforms...
|
||||
|
||||
#else
|
||||
@ -64,13 +80,33 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
#define AURT_ENABLE_HYPER_MUTEX
|
||||
|
||||
#elif defined(AURORA_PLATFORM_LINUX)
|
||||
|
||||
static const auto kPrimitiveSize64Mutex = kPrimitiveSize64LinuxMutex;
|
||||
static const auto kPrimitiveSize64Semaphore = kPrimitiveSize64LinuxSemaphore;
|
||||
static const auto kPrimitiveSize64CS = kPrimitiveSize64LinuxCS;
|
||||
static const auto kPrimitiveSize64Event = kPrimitiveSize64LinuxEvent;
|
||||
static const auto kPrimitiveSize64RWLock = kPrimitiveSize64LinuxRWLock;
|
||||
static const auto kPrimitiveSize64Cond = kPrimitiveSize64LinuxCond;
|
||||
static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64LinuxCondMutex;
|
||||
|
||||
static const auto kPrimitiveSize32Mutex = kPrimitiveSize32LinuxMutex;
|
||||
static const auto kPrimitiveSize32Semaphore = kPrimitiveSize32LinuxSemaphore;
|
||||
static const auto kPrimitiveSize32CS = kPrimitiveSize32LinuxCS;
|
||||
static const auto kPrimitiveSize32Event = kPrimitiveSize32LinuxEvent;
|
||||
static const auto kPrimitiveSize32RWLock = kPrimitiveSize32LinuxRWLock;
|
||||
static const auto kPrimitiveSize32Cond = kPrimitiveSize32LinuxCond;
|
||||
static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32LinuxCondMutex;
|
||||
|
||||
#define AURT_ENABLE_HYPER_MUTEX
|
||||
|
||||
#else
|
||||
|
||||
static const auto kPrimitiveSize64Mutex = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64Semaphore = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64CS = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64Event = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64 * 2;
|
||||
static const auto kPrimitiveSize64Cond = kDefaultPrimitiveSize64;
|
||||
static const auto kPrimitiveSize64CondMutex = kDefaultPrimitiveSize64;
|
||||
|
||||
|
@ -187,7 +187,10 @@ namespace Aurora::Async
|
||||
|
||||
void DeinitSched()
|
||||
{
|
||||
gThread->SendExitSignal();
|
||||
if (gThread)
|
||||
{
|
||||
gThread->SendExitSignal();
|
||||
}
|
||||
gSchedCondvar->Broadcast();
|
||||
gThread.reset();
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ namespace Crypto
|
||||
yarrow_start(&gPrng);
|
||||
|
||||
gHashTiger = register_hash(&tiger_desc);
|
||||
register_hash(&md5_desc);
|
||||
gHashSha1 = register_hash(&sha1_desc);
|
||||
gHashSha256 = register_hash(&sha256_desc);
|
||||
gHashSha384 = register_hash(&sha384_desc);
|
||||
|
@ -123,8 +123,9 @@ static void Pump()
|
||||
::LinuxSuperSecretIOTick();
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(AURORA_PLATFORM_WIN32)
|
||||
Aurora::Win32DropSchedulerResolution();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void RuntimeLateClean();
|
||||
|
@ -197,7 +197,7 @@ namespace Aurora::Compression
|
||||
{
|
||||
size_t outNext {};
|
||||
uint8_t *pOut {};
|
||||
while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState));
|
||||
while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState))
|
||||
{
|
||||
auto [pMainDOut, uMainDOutLength] = this->GetDOutPair();
|
||||
|
||||
|
@ -10,12 +10,11 @@
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
void PlatformHandleFatal(bool fatal)
|
||||
void PlatformHandleFatal(bool fatal, bool bNoExit)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void InitUNIX()
|
||||
{
|
||||
|
||||
|
@ -39,10 +39,10 @@ namespace Aurora::Grug
|
||||
pArrow->pCallback = pCallback;
|
||||
pArrow->pCallbackRunaway = pCallbackRunaway;
|
||||
|
||||
#if defined(ARROW_NO_MUTEX)
|
||||
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
|
||||
#else
|
||||
#if !defined(ARROW_NO_MUTEX)
|
||||
SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer());
|
||||
#else
|
||||
SignalSafeSleepLockYield(&pArrow->spinSemaphore);
|
||||
#endif
|
||||
|
||||
{
|
||||
@ -113,7 +113,9 @@ namespace Aurora::Grug
|
||||
auto lastCallback = last->pCallbackRunaway;
|
||||
|
||||
last->spinSemaphore.Unlock();
|
||||
#if !defined(ARROW_NO_MUTEX)
|
||||
last->spinSemaphore2->Unlock();
|
||||
#endif
|
||||
gReservedArrows.pop_back();
|
||||
|
||||
|
||||
|
@ -93,6 +93,7 @@ namespace Aurora::IO
|
||||
if (create.bDirectIOMode)
|
||||
{
|
||||
dwFlags |= FILE_FLAG_NO_BUFFERING;
|
||||
this->bDirectIOMode = true;
|
||||
}
|
||||
|
||||
if (!dwFlags)
|
||||
|
174
Source/IO/AuIOHandle.Unix.cpp
Normal file
174
Source/IO/AuIOHandle.Unix.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuIOHandle.Unix.cpp
|
||||
Date: 2023-8-11
|
||||
Author: Reece
|
||||
***/
|
||||
#include <RuntimeInternal.hpp>
|
||||
#include "AuIOHandle.hpp"
|
||||
#include "AuIOHandle.Unix.hpp"
|
||||
|
||||
#include "FS/FS.hpp"
|
||||
#include "FS/FileAdvisory.Unix.hpp"
|
||||
#include "FS/FileStream.Unix.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
||||
{
|
||||
int fd = dup(uOSHandle);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return AuUInt64(fd);
|
||||
}
|
||||
|
||||
void AFileHandle::CloseHandle(AuUInt64 uOSHandle)
|
||||
{
|
||||
int fd = (int)uOSHandle;
|
||||
if (fd < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
struct UnixIOHandle final : AFileHandle
|
||||
{
|
||||
bool InitFromPath(HandleCreate create) override
|
||||
{
|
||||
int iFileDescriptor { -1 };
|
||||
|
||||
if (create.path.empty())
|
||||
{
|
||||
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileOpenModeIsValid(create.eMode))
|
||||
{
|
||||
SysPushErrorParam("Invalid open mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorParam("Invalid lock mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pathex = FS::NormalizePathRet(create.path);
|
||||
if (pathex.empty())
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bAsyncHandle ||
|
||||
create.bDirectIOMode)
|
||||
{
|
||||
this->bDirectIO = true;
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
if (create.bAlwaysCreateDirTree)
|
||||
{
|
||||
FS::CreateDirectories(pathex, true);
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (AuFS::FileExists(pathex.c_str()))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
iFileDescriptor = ::open(pathex.c_str(),
|
||||
(create.eMode == FS::EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC | (this->bDirectIO ? O_DIRECT : 0),
|
||||
0664);
|
||||
|
||||
if (iFileDescriptor < 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::ApplyDumbAdvisoryLock(iFileDescriptor, create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (FS::PosixGetLength(iFileDescriptor))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this->bIsAsync = create.bAsyncHandle;
|
||||
|
||||
this->path = create.path;
|
||||
|
||||
return this->IsValid();
|
||||
}
|
||||
};
|
||||
|
||||
AUKN_SYM IIOHandle *IOHandleNew()
|
||||
{
|
||||
return _new UnixIOHandle();
|
||||
}
|
||||
|
||||
AUKN_SYM void IOHandleRelease(IIOHandle *pIOHandle)
|
||||
{
|
||||
AuSafeDelete<UnixIOHandle *>(pIOHandle);
|
||||
}
|
||||
|
||||
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, IOHandle, UnixIOHandle)
|
||||
}
|
13
Source/IO/AuIOHandle.Unix.hpp
Normal file
13
Source/IO/AuIOHandle.Unix.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuIOHandle.Unix.hpp
|
||||
Date: 2023-8-11
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
|
||||
}
|
@ -7,6 +7,11 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IO::IPC
|
||||
{
|
||||
struct IPCPipeImpl;
|
||||
}
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
struct AFileHandle : IIOHandle
|
||||
@ -48,6 +53,8 @@ namespace Aurora::IO
|
||||
AuSPtr<IIOHandle> pThat;
|
||||
bool bIsAsync {};
|
||||
AuString path;
|
||||
IPC::IPCPipeImpl *pIPCPipe {};
|
||||
bool bDirectIO {};
|
||||
|
||||
protected:
|
||||
// Implement me:
|
||||
|
@ -17,9 +17,12 @@
|
||||
#include "FileStream.Unix.hpp"
|
||||
#include "Async.Linux.hpp"
|
||||
#include <Source/IO/IPC/AuIPCPipe.Unix.hpp>
|
||||
#include <Source/IO/AuIOHandle.hpp>
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
#define IPC_PIPE AuStaticCast<AFileHandle>(this->pHandle_)->pIPCPipe
|
||||
|
||||
struct LinuxAsyncFileTransactionLoopSource : Aurora::IO::Loop::LSEvent
|
||||
{
|
||||
LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that);
|
||||
@ -38,16 +41,16 @@ namespace Aurora::IO::FS
|
||||
AuList<AuUInt> handles_;
|
||||
};
|
||||
|
||||
LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that) : caller_(that), Loop::LSEvent(false, false, true)
|
||||
LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr<LinuxAsyncFileTransaction> that) :
|
||||
caller_(that),
|
||||
Loop::LSEvent(false, false, true)
|
||||
{
|
||||
if (that)
|
||||
{
|
||||
auto possiblePipe = that->GetFileHandle()->pIPCPipe;
|
||||
if (possiblePipe)
|
||||
if (auto pPipe = AuStaticCast<AFileHandle>(that->GetFileHandle())->pIPCPipe)
|
||||
{
|
||||
this->bExMode = true;
|
||||
|
||||
this->handles_ = {possiblePipe->GetPreemptFd(), Loop::LSEvent::GetHandle()};
|
||||
this->handles_ = {pPipe->GetPreemptFd(), Loop::LSEvent::GetHandle()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,80 +97,9 @@ namespace Aurora::IO::FS
|
||||
{
|
||||
}
|
||||
|
||||
FileHandle::~FileHandle()
|
||||
void LinuxAsyncFileStream::Init(const AuSPtr<IIOHandle> &handle)
|
||||
{
|
||||
if ((this->readHandle != 0) &&
|
||||
(this->readHandle != -1))
|
||||
{
|
||||
::close(this->readHandle);
|
||||
}
|
||||
|
||||
if ((this->writeHandle != 0) &&
|
||||
(this->writeHandle != -1) &&
|
||||
(this->writeHandle != this->readHandle))
|
||||
{
|
||||
::close(this->writeHandle);
|
||||
}
|
||||
|
||||
this->readHandle = this->writeHandle = -1;
|
||||
}
|
||||
|
||||
bool FileHandle::Init(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock)
|
||||
{
|
||||
int fileHandle;
|
||||
int fOpenMode;
|
||||
|
||||
auto pathex = NormalizePathRet(path);
|
||||
if (pathex.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fOpenMode = openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT);
|
||||
if (bDirectIO)
|
||||
{
|
||||
fOpenMode |= O_DIRECT;
|
||||
}
|
||||
|
||||
fileHandle = ::open(pathex.c_str(),
|
||||
fOpenMode,
|
||||
0664);
|
||||
|
||||
if (fileHandle == -1)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ApplyDumbAdvisoryLock(fileHandle, lock))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
this->directIO = bDirectIO;
|
||||
this->readHandle = this->writeHandle = fileHandle;
|
||||
this->readOnly = openMode == EFileOpenMode::eRead;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileHandle::Init(int read, int write)
|
||||
{
|
||||
this->readHandle = read;
|
||||
this->writeHandle = write;
|
||||
this->directIO = true;
|
||||
this->readOnly = false;
|
||||
}
|
||||
|
||||
|
||||
AuSPtr<FileHandle> LinuxAsyncFileStream::GetHandle()
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
void LinuxAsyncFileStream::Init(const AuSPtr<FileHandle> &handle)
|
||||
{
|
||||
this->handle_ = handle;
|
||||
this->pHandle_ = handle;
|
||||
}
|
||||
|
||||
AuSPtr<IAsyncTransaction> LinuxAsyncFileStream::NewTransaction()
|
||||
@ -178,7 +110,7 @@ namespace Aurora::IO::FS
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!shared->Init(this->handle_))
|
||||
if (!shared->Init(this->pHandle_))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
@ -188,32 +120,53 @@ namespace Aurora::IO::FS
|
||||
|
||||
bool LinuxAsyncFileStream::BlockingTruncate(AuUInt64 length)
|
||||
{
|
||||
return ::ftruncate(this->handle_->writeHandle, length) != -1;
|
||||
}
|
||||
|
||||
bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters)
|
||||
{
|
||||
if (this->handle_->bReadLock)
|
||||
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->handle_->pIPCPipe)
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
if (this->handle_->pIPCPipe->LIOS_PopOne())
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::ftruncate(fd, length) != -1;
|
||||
}
|
||||
|
||||
bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters)
|
||||
{
|
||||
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IPC_PIPE)
|
||||
{
|
||||
if (IPC_PIPE->LIOS_PopOne())
|
||||
{
|
||||
parameters.outVariable = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PosixSetOffset(this->handle_->readHandle, offset))
|
||||
if (!PosixSetOffset(fd, offset))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AuUInt32 read;
|
||||
if (!PosixRead(this->handle_->readHandle, parameters.ptr, parameters.length, &read))
|
||||
if (!PosixRead(fd, parameters.ptr, parameters.length, &read))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -223,18 +176,26 @@ namespace Aurora::IO::FS
|
||||
|
||||
bool LinuxAsyncFileStream::BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters)
|
||||
{
|
||||
if (this->handle_->bWriteLock)
|
||||
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PosixSetOffset(this->handle_->writeHandle, offset))
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PosixSetOffset(fd, offset))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AuUInt32 read;
|
||||
if (!PosixWrite(this->handle_->writeHandle, parameters.ptr, parameters.length, &read))
|
||||
if (!PosixWrite(fd, parameters.ptr, parameters.length, &read))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -242,9 +203,9 @@ namespace Aurora::IO::FS
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinuxAsyncFileTransaction::Init(const AuSPtr<FileHandle> &handle)
|
||||
bool LinuxAsyncFileTransaction::Init(const AuSPtr<IIOHandle> &handle)
|
||||
{
|
||||
this->handle_ = handle;
|
||||
this->pHandle_ = handle;
|
||||
this->loopSource_ = AuMakeShared<LinuxAsyncFileTransactionLoopSource>(AuSharedFromThis());
|
||||
return bool(this->loopSource_);
|
||||
}
|
||||
@ -262,16 +223,16 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
auto fd = this->handle_->readHandle;
|
||||
if (fd == -1)
|
||||
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->handle_->bReadLock)
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -293,9 +254,9 @@ namespace Aurora::IO::FS
|
||||
LIOS_Init(AuSharedFromThis());
|
||||
SetMemory(memoryView);
|
||||
|
||||
if (this->handle_->pIPCPipe)
|
||||
if (IPC_PIPE)
|
||||
{
|
||||
if (this->handle_->pIPCPipe->LIOS_PopOne())
|
||||
if (IPC_PIPE->LIOS_PopOne())
|
||||
{
|
||||
LIOS_SendProcess(0, false, errno);
|
||||
return true;
|
||||
@ -304,7 +265,7 @@ namespace Aurora::IO::FS
|
||||
|
||||
offset += this->uBaseOffset;
|
||||
|
||||
if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(this->handle_->pIPCPipe)))
|
||||
if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(IPC_PIPE)))
|
||||
{
|
||||
LIOS_SendProcess(0, true, errno);
|
||||
return true;
|
||||
@ -328,12 +289,13 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->handle_->bWriteLock)
|
||||
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fd = this->handle_->writeHandle;
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
@ -398,11 +360,11 @@ namespace Aurora::IO::FS
|
||||
|
||||
if (read)
|
||||
{
|
||||
if (this->handle_->pIPCPipe)
|
||||
if (IPC_PIPE)
|
||||
{
|
||||
// Return value intentionally ignored
|
||||
// We just need to poke on read...
|
||||
this->handle_->pIPCPipe->LIOS_PopOne();
|
||||
IPC_PIPE->LIOS_PopOne();
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,9 +433,9 @@ namespace Aurora::IO::FS
|
||||
return WaitMultiple(files, timeout);
|
||||
}
|
||||
|
||||
AuSPtr<FileHandle> LinuxAsyncFileTransaction::GetFileHandle()
|
||||
AuSPtr<IIOHandle> LinuxAsyncFileTransaction::GetFileHandle()
|
||||
{
|
||||
return this->handle_;
|
||||
return this->pHandle_;
|
||||
}
|
||||
|
||||
AuSPtr<Loop::ILoopSource> LinuxAsyncFileTransaction::NewLoopSource()
|
||||
@ -483,38 +445,35 @@ namespace Aurora::IO::FS
|
||||
|
||||
AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock)
|
||||
{
|
||||
AuSPtr<FileHandle> fileHandle;
|
||||
LinuxAsyncFileStream *stream;
|
||||
|
||||
if (path.empty())
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
if (!pHandle)
|
||||
{
|
||||
SysPushErrorParam("Empty path");
|
||||
return {};
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!EFileOpenModeIsValid(openMode))
|
||||
{
|
||||
SysPushErrorParam("Invalid open mode");
|
||||
return {};
|
||||
}
|
||||
AuIO::IIOHandle::HandleCreate createhandle(path);
|
||||
createhandle.eAdvisoryLevel = lock;
|
||||
createhandle.eMode = openMode;
|
||||
createhandle.bFailIfNonEmptyFile = false;
|
||||
createhandle.bDirectIOMode = bDirectIO;
|
||||
createhandle.bAsyncHandle = true;
|
||||
|
||||
fileHandle = AuMakeShared<FileHandle>();
|
||||
if (!fileHandle->Init(path, openMode, bDirectIO, lock))
|
||||
if (!pHandle->InitFromPath(createhandle))
|
||||
{
|
||||
SysPushErrorNested();
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
stream = _new LinuxAsyncFileStream();
|
||||
if (!stream)
|
||||
auto pStream = _new LinuxAsyncFileStream();
|
||||
if (!pStream)
|
||||
{
|
||||
SysPushErrorMem();
|
||||
return {};
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
stream->Init(fileHandle);
|
||||
|
||||
return stream;
|
||||
pStream->Init(pHandle);
|
||||
return pStream;
|
||||
}
|
||||
|
||||
AUKN_SYM void OpenAsyncRelease(IAsyncFileStream *handle)
|
||||
|
@ -17,25 +17,6 @@ namespace Aurora::IO::FS
|
||||
struct LinuxAsyncFileTransaction;
|
||||
struct LinuxAsyncFileTransactionLoopSource;
|
||||
|
||||
struct FileHandle
|
||||
{
|
||||
~FileHandle();
|
||||
|
||||
bool Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock);
|
||||
void Init(int read, int write);
|
||||
|
||||
int readHandle {-1};
|
||||
int writeHandle {-1};
|
||||
|
||||
AuString path;
|
||||
bool readOnly;
|
||||
bool directIO;
|
||||
IPC::IPCPipeImpl *pIPCPipe {};
|
||||
bool bNoOwns { false };
|
||||
bool bWriteLock { false };
|
||||
bool bReadLock { false };
|
||||
};
|
||||
|
||||
struct LinuxAsyncFileStream : IAsyncFileStream
|
||||
{
|
||||
AuSPtr<IAsyncTransaction> NewTransaction() override;
|
||||
@ -43,12 +24,12 @@ namespace Aurora::IO::FS
|
||||
bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) override;
|
||||
bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) override;
|
||||
|
||||
void Init(const AuSPtr<FileHandle> &handle);
|
||||
void Init(const AuSPtr<IIOHandle> &handle);
|
||||
|
||||
AuSPtr<FileHandle> GetHandle();
|
||||
AuSPtr<IIOHandle> GetHandle();
|
||||
|
||||
private:
|
||||
AuSPtr<FileHandle> handle_;
|
||||
AuSPtr<IIOHandle> pHandle_;
|
||||
};
|
||||
|
||||
|
||||
@ -56,7 +37,7 @@ namespace Aurora::IO::FS
|
||||
{
|
||||
~LinuxAsyncFileTransaction();
|
||||
|
||||
bool Init(const AuSPtr<FileHandle> &handle);
|
||||
bool Init(const AuSPtr<IIOHandle> &handle);
|
||||
|
||||
bool StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView) override;
|
||||
bool StartWrite(AuUInt64 offset, const AuSPtr<AuMemoryViewRead> &memoryView) override;
|
||||
@ -78,14 +59,14 @@ namespace Aurora::IO::FS
|
||||
void Reset() override;
|
||||
|
||||
void DispatchCb();
|
||||
AuSPtr<FileHandle> GetFileHandle();
|
||||
AuSPtr<IIOHandle> GetFileHandle();
|
||||
|
||||
void SetBaseOffset(AuUInt64 uBaseOffset) override;
|
||||
|
||||
virtual void LIOS_Process(AuUInt32 read, bool failure, int err, bool mark) override;
|
||||
|
||||
private:
|
||||
AuSPtr<FileHandle> handle_;
|
||||
AuSPtr<IIOHandle> pHandle_;
|
||||
AuUInt64 lastAbstractOffset_ {};
|
||||
AuUInt32 lastFinishedStat_ {};
|
||||
AuUInt64 uBaseOffset {};
|
||||
|
@ -302,8 +302,8 @@ namespace Aurora::IO::FS
|
||||
AUKN_SYM bool Relink(const AuString &src, const AuString &dest)
|
||||
{
|
||||
auto normalizedDestPath = NormalizePathRet(dest);
|
||||
CreateDirectories(destPathNormalized, true);
|
||||
return ::rename(NormalizePathRet(src).c_str(), destPathNormalized.c_str()) != -1;
|
||||
CreateDirectories(normalizedDestPath, true);
|
||||
return ::rename(NormalizePathRet(src).c_str(), normalizedDestPath.c_str()) != -1;
|
||||
}
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
@ -419,9 +419,9 @@ namespace Aurora::IO::FS
|
||||
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctime_nsec);
|
||||
stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtime_nsec);
|
||||
stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atime_nsec);
|
||||
stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctim.tv_nsec);
|
||||
stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtim.tv_nsec);
|
||||
stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atim.tv_nsec);
|
||||
#else
|
||||
stat.createdNs = AuMSToNS<AuUInt64>(Time::CTimeToMS(s.st_ctime));
|
||||
stat.modifiedNs = AuMSToNS<AuUInt64>(Time::CTimeToMS(s.st_mtime));
|
||||
|
@ -66,8 +66,8 @@ namespace Aurora::IO::FS
|
||||
|
||||
timeval timeVals[2];
|
||||
|
||||
ConvertFileTime(&timeVals[0], auStat.accessed, times.accessedNs);
|
||||
ConvertFileTime(&timeVals[1], auStat.modified, times.modifiedNs);
|
||||
ConvertFileTime(&timeVals[0], auStat.accessedNs, times.accessedNs);
|
||||
ConvertFileTime(&timeVals[1], auStat.modifiedNs, times.modifiedNs);
|
||||
|
||||
bool bRet = ::utimes(pathex.c_str(), timeVals) == 0;
|
||||
if (!bRet)
|
||||
|
@ -19,7 +19,7 @@ namespace Aurora::IO::FS
|
||||
AuString buffer;
|
||||
|
||||
auto srcPath = NormalizePathRet(path);
|
||||
if (pathex.empty())
|
||||
if (srcPath.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
@ -30,7 +30,7 @@ namespace Aurora::IO::FS
|
||||
return {};
|
||||
}
|
||||
|
||||
auto length = ::listxattr(srcPath.c_str(), attr.c_str(), buffer.data(), buffer.size(), 0 /*no follow symlinks*/);
|
||||
auto length = ::listxattr(srcPath.c_str(), buffer.data(), buffer.size());
|
||||
if (length < 0)
|
||||
{
|
||||
SysPushErrorIO("Error listing attributes");
|
||||
@ -51,12 +51,12 @@ namespace Aurora::IO::FS
|
||||
AuByteBuffer buffer;
|
||||
|
||||
auto srcPath = NormalizePathRet(path);
|
||||
if (pathex.empty())
|
||||
if (srcPath.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0, 0 /*no follow symlinks*/);
|
||||
auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0);
|
||||
if (length < 0)
|
||||
{
|
||||
SysPushErrorIO("Error reading attribute");
|
||||
@ -74,7 +74,7 @@ namespace Aurora::IO::FS
|
||||
return {};
|
||||
}
|
||||
|
||||
length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length, 0 /*no follow symlinks*/);
|
||||
length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length);
|
||||
if (length < 0)
|
||||
{
|
||||
SysPushErrorIO("Error reading attribute");
|
||||
@ -89,7 +89,7 @@ namespace Aurora::IO::FS
|
||||
AUKN_SYM bool FileAttrsSet(const AuString &path, const AuString &attr, const Memory::MemoryViewRead &view)
|
||||
{
|
||||
auto srcPath = NormalizePathRet(path);
|
||||
if (pathex.empty())
|
||||
if (srcPath.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -112,7 +112,7 @@ namespace Aurora::IO::FS
|
||||
AUKN_SYM bool FileAttrsDel(const AuString &path, const AuString &attr)
|
||||
{
|
||||
auto srcPath = NormalizePathRet(path);
|
||||
if (pathex.empty())
|
||||
if (srcPath.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -126,57 +126,81 @@ namespace Aurora::IO::FS
|
||||
Close();
|
||||
}
|
||||
|
||||
bool PosixFileStream::Init(int handle, const AuString &path)
|
||||
bool PosixFileStream::Init(AuSPtr<IIOHandle> pHandle)
|
||||
{
|
||||
AuCtorCode_t code;
|
||||
|
||||
this->handle_ = handle;
|
||||
this->path_ = AuTryConstruct<AuString>(code, path);
|
||||
if (!code)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->pHandle_ = pHandle;
|
||||
return true;
|
||||
}
|
||||
|
||||
AuUInt64 PosixFileStream::GetOffset()
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinlock_);
|
||||
|
||||
if (this->handle_ == -1)
|
||||
|
||||
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
iOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||
}
|
||||
|
||||
return PosixGetOffset(this->handle_);
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
return PosixGetOffset(fd);
|
||||
}
|
||||
|
||||
bool PosixFileStream::SetOffset(AuUInt64 offset)
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinlock_);
|
||||
|
||||
if (this->handle_ == -1)
|
||||
|
||||
auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
iOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||
}
|
||||
|
||||
if (!iOptSafe)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return PosixSetOffset(this->handle_, offset);
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
return PosixSetOffset(fd, offset);
|
||||
}
|
||||
|
||||
AuUInt64 PosixFileStream::GetLength()
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinlock_);
|
||||
|
||||
if (this->handle_ == -1)
|
||||
|
||||
auto iOptSafe = this->pHandle_->GetOSReadHandleSafe();
|
||||
if (!iOptSafe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fd = (int)iOptSafe.Value();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return PosixGetLength(this->handle_);
|
||||
return PosixGetLength(fd);
|
||||
}
|
||||
|
||||
bool PosixFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters)
|
||||
@ -185,7 +209,14 @@ namespace Aurora::IO::FS
|
||||
|
||||
parameters.outVariable = 0;
|
||||
|
||||
if (this->handle_ == -1)
|
||||
if (!this->pHandle_)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd = this->GetUnixHandle();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
@ -199,7 +230,7 @@ namespace Aurora::IO::FS
|
||||
|
||||
int blockSize = AuMin(kFileCopyBlock, length);
|
||||
|
||||
if (!PosixRead(handle_, &reinterpret_cast<char *>(parameters.ptr)[offset], blockSize, &read))
|
||||
if (!PosixRead(fd, &reinterpret_cast<char *>(parameters.ptr)[offset], blockSize, &read))
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
break;
|
||||
@ -222,7 +253,14 @@ namespace Aurora::IO::FS
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinlock_);
|
||||
|
||||
if (this->handle_ == -1)
|
||||
if (!this->pHandle_)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd = this->GetUnixHandle();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return 0;
|
||||
@ -238,9 +276,9 @@ namespace Aurora::IO::FS
|
||||
|
||||
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
|
||||
|
||||
if (!PosixWrite(this->handle_, &reinterpret_cast<const char *>(parameters.ptr)[offset], blockSize, &written))
|
||||
if (!PosixWrite(fd, &reinterpret_cast<const char *>(parameters.ptr)[offset], blockSize, &written))
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
SysPushErrorNested("File Error: {}", this->pHandle_->GetPath());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -265,26 +303,40 @@ namespace Aurora::IO::FS
|
||||
|
||||
void PosixFileStream::Close()
|
||||
{
|
||||
int handle = AuExchange(this->handle_, -1);
|
||||
if (handle != -1)
|
||||
{
|
||||
::close(handle);
|
||||
}
|
||||
auto pHandle = this->pHandle_;
|
||||
AuResetMember(this->pHandle_);
|
||||
|
||||
if (AuExchange(this->bMadeTemporary, false))
|
||||
{
|
||||
::unlink(this->path_.c_str());
|
||||
if (pHandle)
|
||||
{
|
||||
::unlink(pHandle->GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PosixFileStream::Flush()
|
||||
{
|
||||
::fsync(this->handle_);
|
||||
int fd = this->GetUnixHandle();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return;
|
||||
}
|
||||
|
||||
::fsync(fd);
|
||||
}
|
||||
|
||||
void PosixFileStream::WriteEoS()
|
||||
{
|
||||
::ftruncate(this->handle_, GetOffset());
|
||||
int fd = this->GetUnixHandle();
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorUninitialized();
|
||||
return;
|
||||
}
|
||||
|
||||
::ftruncate(fd, GetOffset());
|
||||
}
|
||||
|
||||
void PosixFileStream::MakeTemporary()
|
||||
@ -292,70 +344,72 @@ namespace Aurora::IO::FS
|
||||
this->bMadeTemporary = true;
|
||||
}
|
||||
|
||||
int PosixFileStream::GetHandle()
|
||||
int PosixFileStream::GetUnixHandle()
|
||||
{
|
||||
return this->handle_;
|
||||
return this->pHandle_ ?
|
||||
(int)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)-1)) :
|
||||
-1;
|
||||
}
|
||||
|
||||
static IFileStream *OpenNewEx(const AuString &path, EFileOpenMode openMode, EFileAdvisoryLockLevel lock, bool bCheck)
|
||||
AuSPtr<IIOHandle> PosixFileStream::GetHandle()
|
||||
{
|
||||
auto pathex = NormalizePathRet(path);
|
||||
return this->pHandle_;
|
||||
}
|
||||
|
||||
if (openMode != EFileOpenMode::eRead)
|
||||
AUKN_SYM AuSPtr<IFileStream> OpenBlockingFileStreamFromHandle(AuSPtr<IIOHandle> pIOHandle)
|
||||
{
|
||||
auto pStream = AuMakeShared<PosixFileStream>();
|
||||
if (!pStream)
|
||||
{
|
||||
CreateDirectories(pathex, true);
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (bCheck)
|
||||
pStream->Init(pIOHandle);
|
||||
return pStream;
|
||||
}
|
||||
|
||||
static IFileStream *OpenNewEx(const AuString &path,
|
||||
EFileOpenMode openMode,
|
||||
EFileAdvisoryLockLevel lock,
|
||||
bool bCheck)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (FileExists(path))
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
if (!pHandle)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. Already exists.", path);
|
||||
return false;
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto fileHandle = ::open(pathex.c_str(),
|
||||
(openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC,
|
||||
0664);
|
||||
AuIO::IIOHandle::HandleCreate createhandle(path);
|
||||
createhandle.eAdvisoryLevel = lock;
|
||||
createhandle.eMode = openMode;
|
||||
createhandle.bFailIfNonEmptyFile = bCheck;
|
||||
createhandle.bDirectIOMode = false;
|
||||
createhandle.bAsyncHandle = false;
|
||||
|
||||
if (fileHandle < 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ApplyDumbAdvisoryLock(fileHandle, lock))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (bCheck)
|
||||
{
|
||||
if (PosixGetLength(fileHandle))
|
||||
if (!pHandle->InitFromPath(createhandle))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. Already exists.", path);
|
||||
return false;
|
||||
SysPushErrorNested();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto stream = _new PosixFileStream();
|
||||
if (!stream)
|
||||
auto pStream = _new PosixFileStream();
|
||||
if (!pStream)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pStream->Init(pHandle);
|
||||
return pStream;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
::close(fileHandle);
|
||||
SysPushErrorMem("{}", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!stream->Init(fileHandle, pathex))
|
||||
{
|
||||
delete stream;
|
||||
SysPushErrorGeneric("{}", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
AUKN_SYM IFileStream *CreateNew(const AuString &path)
|
||||
|
@ -13,6 +13,7 @@ namespace Aurora::IO::FS
|
||||
{
|
||||
// Code-sharing for async API fallbacks...
|
||||
bool PosixSetOffset(int fd, AuUInt64 offset);
|
||||
AuUInt64 PosixGetLength(int fd);
|
||||
bool PosixRead(int fd, void *buf, AuUInt32 count, AuUInt32 *pRead);
|
||||
bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
|
||||
|
||||
@ -20,7 +21,7 @@ namespace Aurora::IO::FS
|
||||
{
|
||||
~PosixFileStream();
|
||||
|
||||
bool Init(int handle, const AuString &path);
|
||||
bool Init(AuSPtr<IIOHandle> pHandle);
|
||||
|
||||
AuUInt64 GetOffset() override;
|
||||
bool SetOffset(AuUInt64 offset) override;
|
||||
@ -31,11 +32,11 @@ namespace Aurora::IO::FS
|
||||
void Flush() override;
|
||||
void WriteEoS() override;
|
||||
void MakeTemporary() override;
|
||||
AuSPtr<IIOHandle> GetHandle() override;
|
||||
int GetUnixHandle();
|
||||
|
||||
int GetHandle();
|
||||
private:
|
||||
|
||||
int handle_ = -1;
|
||||
AuSPtr<IIOHandle> pHandle_;
|
||||
AuString path_;
|
||||
AuThreadPrimitives::SpinLock spinlock_;
|
||||
bool bMadeTemporary {};
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include "FileTrust.Unix.hpp"
|
||||
|
||||
#include <sys/xattr.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <Source/IO/AuIOHandle.hpp>
|
||||
|
||||
namespace Aurora::IO::IPC
|
||||
{
|
||||
@ -127,14 +128,16 @@ namespace Aurora::IO::IPC
|
||||
}
|
||||
#endif
|
||||
|
||||
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
||||
|
||||
this->fsHandle_ = AuIO::IOHandleShared();
|
||||
SysAssert(this->fsHandle_);
|
||||
|
||||
this->fsStream_ = AuMakeShared<IO::FS::LinuxAsyncFileStream>();
|
||||
|
||||
this->fsHandle_->pIPCPipe = this;
|
||||
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
|
||||
|
||||
this->fsHandle_->Init(fds2[0], fds2[1]);
|
||||
this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
|
||||
this->fsStream_->Init(this->fsHandle_);
|
||||
|
||||
}
|
||||
|
||||
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelIsOpen()
|
||||
@ -152,6 +155,11 @@ namespace Aurora::IO::IPC
|
||||
return this->fsStream_->NewTransaction();
|
||||
}
|
||||
|
||||
AuSPtr<IO::IIOHandle> IPCPipeImpl::GetCurrentSharedDuplexHandles()
|
||||
{
|
||||
return this->fsHandle_;
|
||||
}
|
||||
|
||||
bool IPCPipeImpl::Read(const Memory::MemoryViewStreamWrite &write, bool nonblock)
|
||||
{
|
||||
auto handle = fds[0];
|
||||
|
@ -53,7 +53,8 @@ namespace Aurora::IO::IPC
|
||||
#endif
|
||||
|
||||
virtual AuSPtr<IO::IAsyncTransaction> NewAsyncTransaction() override;
|
||||
|
||||
virtual AuSPtr<IO::IIOHandle> GetCurrentSharedDuplexHandles() override;
|
||||
|
||||
virtual AuSPtr<Loop::ILoopSource> AsReadChannelIsOpen() override;
|
||||
virtual AuSPtr<Loop::ILoopSource> AsReadChannelHasData() override;
|
||||
|
||||
@ -84,7 +85,7 @@ namespace Aurora::IO::IPC
|
||||
int fds[2] {-1, -1};
|
||||
int secondary[2] {-1, -1};
|
||||
|
||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
||||
AuSPtr<IO::IIOHandle> fsHandle_;
|
||||
AuSPtr<IO::FS::LinuxAsyncFileStream> fsStream_;
|
||||
|
||||
void SendTerminateSignal();
|
||||
|
@ -34,7 +34,16 @@ namespace Aurora::IO::Net
|
||||
Socket::Socket(struct NetInterface *pInterface,
|
||||
struct NetWorker *pWorker,
|
||||
const AuSPtr<ISocketDriver> &pSocketDriver,
|
||||
const NetEndpoint &endpoint) :
|
||||
const AuPair<NetHostname, AuUInt16> &endpoint,
|
||||
AuNet::ETransportProtocol eProtocol) :
|
||||
SocketBase(pInterface, pWorker, pSocketDriver, endpoint, eProtocol)
|
||||
{
|
||||
}
|
||||
|
||||
Socket::Socket(struct NetInterface *pInterface,
|
||||
struct NetWorker *pWorker,
|
||||
const AuSPtr<ISocketDriver> &pSocketDriver,
|
||||
const NetEndpoint &endpoint) :
|
||||
SocketBase(pInterface, pWorker, pSocketDriver, endpoint)
|
||||
{
|
||||
}
|
||||
@ -55,14 +64,48 @@ namespace Aurora::IO::Net
|
||||
|
||||
void Socket::CloseSocket()
|
||||
{
|
||||
if (this->osHandle_ &&
|
||||
this->osHandle_ != -1)
|
||||
this->osHandle_ = 0;
|
||||
AuResetMember(this->osHandleOwner_);
|
||||
}
|
||||
|
||||
void Socket::RenewSocket()
|
||||
{
|
||||
if (!this->SendPreestablish())
|
||||
{
|
||||
::close(this->osHandle_);
|
||||
this->osHandle_ = 0;
|
||||
SysPushErrorIO("Preestablish drop");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->bHasRemoteMany_ && this->connectMany_.ips.size())
|
||||
{
|
||||
this->remoteEndpoint_ = this->connectMany_.ips[0];
|
||||
}
|
||||
|
||||
this->CloseSocket();
|
||||
|
||||
this->osHandle_ = ::socket(
|
||||
IPToDomain(this->remoteEndpoint_),
|
||||
TransportToPlatformType(this->remoteEndpoint_),
|
||||
0
|
||||
);
|
||||
|
||||
if (this->osHandle_ == -1)
|
||||
{
|
||||
this->SendErrorNoStream(GetLastNetError());
|
||||
return;
|
||||
}
|
||||
|
||||
this->osHandleOwner_ = AuIO::IOHandleShared();
|
||||
this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_);
|
||||
|
||||
if (!this->PrepareConnectOperations())
|
||||
{
|
||||
this->bForceFailConstruct_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Socket::FinishConstructAsync()
|
||||
{
|
||||
if (!this->SendPreestablish())
|
||||
@ -83,13 +126,13 @@ namespace Aurora::IO::Net
|
||||
return;
|
||||
}
|
||||
|
||||
this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_);
|
||||
|
||||
if (!this->PrepareConnectOperations())
|
||||
{
|
||||
this->bForceFailConstruct_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->osHandleOwner_->Init((int)this->osHandle_, (int)this->osHandle_);
|
||||
}
|
||||
|
||||
bool Socket::PrepareConnectOperations()
|
||||
|
@ -29,6 +29,12 @@ namespace Aurora::IO::Net
|
||||
const AuSPtr<ISocketDriver> &pSocketDriver,
|
||||
AuUInt osHandle);
|
||||
|
||||
Socket(struct NetInterface *pInterface,
|
||||
struct NetWorker *pWorker,
|
||||
const AuSPtr<ISocketDriver> &pSocketDriver,
|
||||
const AuPair<NetHostname, AuUInt16> &endpoint,
|
||||
AuNet::ETransportProtocol eProtocol);
|
||||
|
||||
Socket(struct NetInterface *pInterface,
|
||||
struct NetWorker *pWorker,
|
||||
const AuSPtr<ISocketDriver> &pSocketDriver,
|
||||
@ -61,6 +67,7 @@ namespace Aurora::IO::Net
|
||||
virtual void Shutdown(bool bNow) override;
|
||||
|
||||
virtual void CloseSocket() override;
|
||||
virtual void RenewSocket() override;
|
||||
|
||||
bool MakeCloseonexec();
|
||||
};
|
||||
|
@ -113,6 +113,8 @@ namespace Aurora::IO::UNIX
|
||||
{
|
||||
static bool LinuxOverlappedSubmit(int fd, int op, AuUInt offset, ASubmittable *context, AuLoop::ILSEvent *optEvent);
|
||||
|
||||
static void IoTlsRedo();
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// ASubmittable
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@ -155,6 +157,8 @@ namespace Aurora::IO::UNIX
|
||||
{
|
||||
SysPushErrorCatch("IO Callback threw an exception");
|
||||
}
|
||||
|
||||
IoTlsRedo();
|
||||
}
|
||||
|
||||
UNIX::SendIOBuffers();
|
||||
@ -274,6 +278,7 @@ namespace Aurora::IO::UNIX
|
||||
aio_context_t context {};
|
||||
AuList<iocb*> submitPendingArray;
|
||||
AuUInt32 dwIoSubmits;
|
||||
bool bPollHit {};
|
||||
|
||||
~TLSIO()
|
||||
{
|
||||
@ -298,6 +303,17 @@ namespace Aurora::IO::UNIX
|
||||
return handle->bInitialized ? handle : nullptr;
|
||||
}
|
||||
|
||||
void IoTlsRedo()
|
||||
{
|
||||
auto pTLS = GetTls();
|
||||
if (!pTLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pTLS->bPollHit = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// TLS IO IMPL
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@ -594,7 +610,7 @@ namespace Aurora::IO::UNIX
|
||||
}
|
||||
}
|
||||
|
||||
} while (timeout);
|
||||
} while (timeout || AuExchange(io->bPollHit, false));
|
||||
|
||||
return dwApcsSent;
|
||||
}
|
||||
@ -730,7 +746,7 @@ namespace Aurora::IO::UNIX
|
||||
}
|
||||
}
|
||||
|
||||
} while (timeout ? !bEpollTriggered : false);
|
||||
} while ((timeout ? !bEpollTriggered : false) || AuExchange(io->bPollHit, false));
|
||||
|
||||
io_event finalEpollEvent {};
|
||||
if ((bEpollTriggered) ||
|
||||
|
@ -39,7 +39,7 @@ namespace Aurora::Process
|
||||
if (key.empty())
|
||||
{
|
||||
SysPushErrorArg("Missing key");
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pValue = ::getenv(key.c_str());
|
||||
|
@ -156,7 +156,6 @@ namespace Aurora::Process
|
||||
|
||||
AuString file;
|
||||
AuIOFS::GetFileFromPath(file, path);
|
||||
|
||||
auto object = AuIOFS::OpenReadUnique(path);
|
||||
if (!object)
|
||||
{
|
||||
@ -169,6 +168,7 @@ namespace Aurora::Process
|
||||
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(&header, sizeof(header)), read)))
|
||||
{
|
||||
SysPushErrorIO();
|
||||
continue;
|
||||
}
|
||||
|
||||
AuList<Elf_Shdr> elfSections;
|
||||
@ -188,10 +188,15 @@ namespace Aurora::Process
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto &strtab = elfSections[header.e_shstrndx];
|
||||
|
||||
AuList<AuUInt8> strHeap;
|
||||
if (strtab.sh_size > 80 * 1024 * 1024)
|
||||
{
|
||||
SysPushErrorMem();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!AuTryResize(strHeap, strtab.sh_size))
|
||||
{
|
||||
SysPushErrorMem();
|
||||
@ -211,6 +216,11 @@ namespace Aurora::Process
|
||||
Sections modSections;
|
||||
for (const auto & section : elfSections)
|
||||
{
|
||||
if (section.sh_name > strHeap.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto len = strnlen((const char *)strHeap.data() + section.sh_name, strHeap.size() - section.sh_name);
|
||||
AuString sectionName((const char *)strHeap.data() + section.sh_name, len);
|
||||
AuUInt fileOffset = section.sh_offset;
|
||||
|
@ -95,7 +95,7 @@ namespace Aurora::Process
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength} });
|
||||
return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength_ } });
|
||||
}
|
||||
|
||||
bool ProcessSectionFileMapView::UnlockSwap()
|
||||
@ -105,6 +105,6 @@ namespace Aurora::Process
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength} });
|
||||
return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength_ } });
|
||||
}
|
||||
}
|
@ -62,17 +62,16 @@ namespace Aurora::Process
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel sectionLock)
|
||||
{
|
||||
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
|
||||
return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr<IProcessSectionMapView> {};
|
||||
return this->MapFileByPathEx(0, str, uOffset, uLength, mode, sectionLock);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObject(const AuSPtr<AuFS::IFileStream> &stream,
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
return this->MapFileByObjectEx(0, stream, uOffset, uLength, mode, processLockLevel);
|
||||
return this->MapFileByObjectEx(0, pIOHandle, uOffset, uLength, mode, processLockLevel);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapIPCMemory(const AuString &handleString,
|
||||
@ -144,18 +143,37 @@ namespace Aurora::Process
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
|
||||
return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr<IProcessSectionMapView> {};
|
||||
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
if (!pHandle)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AuIO::IIOHandle::HandleCreate createhandle(str);
|
||||
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
|
||||
createhandle.eMode = mode;
|
||||
createhandle.bFailIfNonEmptyFile = false;
|
||||
createhandle.bDirectIOMode = false;
|
||||
createhandle.bAsyncHandle = false;
|
||||
|
||||
if (!pHandle->InitFromPath(createhandle))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObjectEx(AuUInt viewOffset,
|
||||
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
|
||||
const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
if (!pStream)
|
||||
if (!pIOHandle)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
@ -166,8 +184,7 @@ namespace Aurora::Process
|
||||
return {};
|
||||
}
|
||||
|
||||
auto ok = AuStaticCast<AuFS::PosixFileStream>(pStream);
|
||||
int fd = ::dup(ok->GetHandle());
|
||||
int fd = ::dup(pIOHandle->GetOSHandle());
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
|
@ -23,7 +23,7 @@ namespace Aurora::Process
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel sectionLock) override;
|
||||
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<Aurora::IO::FS::IFileStream> &stream,
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 offset,
|
||||
AuUInt length,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
@ -46,7 +46,7 @@ namespace Aurora::Process
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override;
|
||||
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObjectEx(AuUInt viewOffset,
|
||||
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
|
||||
const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
|
@ -89,22 +89,21 @@ namespace Aurora::Process
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByPath(const AuString &str,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel sectionLock)
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel sectionLock)
|
||||
{
|
||||
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
|
||||
return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr<IProcessSectionMapView> {};
|
||||
return this->MapFileByPathEx(-1, str, uOffset, uLength, mode, sectionLock);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObject(const AuSPtr<AuFS::IFileStream> &stream,
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
return this->MapFileByObjectEx(-1, stream, uOffset, uLength, mode, processLockLevel);
|
||||
return this->MapFileByObjectEx(-1, pIOHandle, uOffset, uLength, mode, processLockLevel);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapIPCMemory(const AuString &handleString,
|
||||
@ -170,24 +169,42 @@ namespace Aurora::Process
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByPathEx(AuUInt viewOffset,
|
||||
const AuString &str,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
const AuString &str,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety);
|
||||
return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr<IProcessSectionMapView> {};
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
if (!pHandle)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AuIO::IIOHandle::HandleCreate createhandle(str);
|
||||
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
|
||||
createhandle.eMode = mode;
|
||||
createhandle.bFailIfNonEmptyFile = false;
|
||||
createhandle.bDirectIOMode = false;
|
||||
createhandle.bAsyncHandle = false;
|
||||
|
||||
if (!pHandle->InitFromPath(createhandle))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
|
||||
}
|
||||
|
||||
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObjectEx(AuUInt viewOffset,
|
||||
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
|
||||
{
|
||||
if (!pStream)
|
||||
if (!pIOHandle)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
@ -204,8 +221,7 @@ namespace Aurora::Process
|
||||
return {};
|
||||
}
|
||||
|
||||
auto ok = AuStaticCast<AuFS::PosixFileStream>(pStream);
|
||||
int fd = ::dup(ok->GetHandle());
|
||||
int fd = ::dup(pIOHandle->GetOSHandle());
|
||||
if (fd == -1)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
|
@ -30,7 +30,7 @@ namespace Aurora::Process
|
||||
AuFS::EFileOpenMode mode,
|
||||
AuFS::EFileAdvisoryLockLevel sectionLock) override;
|
||||
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<Aurora::IO::FS::IFileStream> &stream,
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObject(const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 offset,
|
||||
AuUInt length,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
@ -53,7 +53,7 @@ namespace Aurora::Process
|
||||
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override;
|
||||
|
||||
AuSPtr<IProcessSectionMapView> MapFileByObjectEx(AuUInt viewOffset,
|
||||
const AuSPtr<Aurora::IO::FS::IFileStream> &pStream,
|
||||
const AuSPtr<IO::IIOHandle> &pIOHandle,
|
||||
AuUInt64 uOffset,
|
||||
AuUInt uLength,
|
||||
Aurora::IO::FS::EFileOpenMode mode,
|
||||
|
@ -154,7 +154,7 @@ namespace Aurora::Processes
|
||||
{
|
||||
if (::kill(this->pidt_, SIGTERM) == 0)
|
||||
{
|
||||
return this->finished_->Lock(500);
|
||||
return this->finished_->LockMS(500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,6 +283,9 @@ namespace Aurora::Processes
|
||||
fds[0] = ::open("/dev/null", O_RDWR);
|
||||
fds[1] = ::open("/dev/null", O_RDWR);
|
||||
break;
|
||||
case EStreamForward::eNewConsoleWindow:
|
||||
SysPushErrorGeneric("AuProcesses is not the right place for PTY support. At least not in this form (this level of abstraction only cares for pipes).");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -310,7 +313,7 @@ namespace Aurora::Processes
|
||||
if ((this->startup_.fwdIn == EStreamForward::eAsyncPipe) ||
|
||||
(this->startup_.fwdOut == EStreamForward::eAsyncPipe))
|
||||
{
|
||||
this->fsHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
||||
this->fsHandle_ = AuIO::IOHandleShared();
|
||||
if (!this->fsHandle_)
|
||||
{
|
||||
return false;
|
||||
@ -322,13 +325,13 @@ namespace Aurora::Processes
|
||||
return false;
|
||||
}
|
||||
|
||||
this->fsHandle_->Init(this->pipeStdOut_[0], this->pipeStdIn_[1]);
|
||||
this->fsHandle_->InitFromPairMove(this->pipeStdOut_[0], this->pipeStdIn_[1]);
|
||||
this->fsStream_->Init(this->fsHandle_);
|
||||
}
|
||||
|
||||
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
||||
{
|
||||
this->fsErrorHandle_ = AuMakeShared<IO::FS::FileHandle>();
|
||||
this->fsErrorHandle_ = AuIO::IOHandleShared();
|
||||
if (!this->fsErrorHandle_)
|
||||
{
|
||||
return false;
|
||||
@ -340,7 +343,7 @@ namespace Aurora::Processes
|
||||
return false;
|
||||
}
|
||||
|
||||
this->fsErrorHandle_->Init(this->pipeStdErr_[0], -1);
|
||||
this->fsErrorHandle_->InitFromPairMove(this->pipeStdErr_[0], -1);
|
||||
this->fsErrorStream_->Init(this->fsErrorHandle_);
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,10 @@ namespace Aurora::Processes
|
||||
|
||||
AuSPtr<IO::Loop::ILSEvent> loopSource_;
|
||||
|
||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
||||
AuSPtr<IO::IIOHandle> fsHandle_;
|
||||
AuSPtr<ProcessPipeFileStream> fsStream_;
|
||||
|
||||
AuSPtr<IO::FS::FileHandle> fsErrorHandle_;
|
||||
AuSPtr<IO::IIOHandle> fsErrorHandle_;
|
||||
AuSPtr<ProcessPipeFileStream> fsErrorStream_;
|
||||
|
||||
AuThreadPrimitives::EventShared_t finished_;
|
||||
|
@ -175,7 +175,7 @@ namespace Aurora::RNG
|
||||
acc = a = b = c = 0;
|
||||
bits = 8;
|
||||
|
||||
void *pASLRSeed = &RngTimeBased;
|
||||
void *pASLRSeed = (void *)&RngTimeBased;
|
||||
|
||||
for (AU_ITERATE_N(uOffsetInByteStream, uLen))
|
||||
{
|
||||
|
@ -13,6 +13,12 @@
|
||||
#include <timeapi.h>
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <Time/Time.hpp>
|
||||
|
||||
#define HACK_NO_INVALID_ACCESS_LEAK_SHARED_REF_ON_DESTROYED_THREAD
|
||||
@ -27,6 +33,13 @@ namespace Aurora::Threading
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
||||
const struct timespec *timeout,
|
||||
uint32_t *uaddr2, uint32_t val3)
|
||||
{
|
||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
}
|
||||
|
||||
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
||||
{
|
||||
if (timeout)
|
||||
@ -466,17 +479,17 @@ namespace Aurora::Threading
|
||||
|
||||
static bool RunOSWaitOnAddressNoTimed(const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 dwWordSize)
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
return pWaitOnAddress((void *)pTargetAddress, (void *)pCompareAddress, dwWordSize, INFINITE);
|
||||
return pWaitOnAddress((void *)pTargetAddress, (void *)pCompareAddress, uWordSize, INFINITE);
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
int ret {};
|
||||
|
||||
#if defined(AU_CPU_ENDIAN_BIG)
|
||||
if (dwWordSize == 8)
|
||||
if (uWordSize == 8)
|
||||
{
|
||||
pTargetAddress = AuReinterpretCast<const char *>(pTargetAddress) + 4;
|
||||
pCompareAddress = AuReinterpretCast<const char *>(pCompareAddress) + 4;
|
||||
@ -679,7 +692,7 @@ namespace Aurora::Threading
|
||||
auto uCurrent = *(AuUInt32 *)pCompareAddress;
|
||||
|
||||
struct timespec tspec;
|
||||
Time::auabsns2ts(&tspec, uAbsTimeAltClock ? uAbsTimeAltClock.value() : uAbsTimeSteadyClock);
|
||||
Time::monoabsns2ts(&tspec, uAbsTimeAltClock ? uAbsTimeAltClock.value() : uAbsTimeSteadyClock);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) : mutex_(std::dynamic_pointer_cast<IConditionMutexEx>(mutex))
|
||||
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &pMutex) :
|
||||
mutex_(AuStaticCast<UnixConditionMutex>(pMutex))
|
||||
{
|
||||
pthread_condattr_t attr;
|
||||
|
||||
@ -41,14 +42,20 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool ConditionVariableImpl::WaitForSignalNS(AuUInt64 qwTimeout)
|
||||
{
|
||||
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_->GetOSHandle());
|
||||
return WaitForSignalNsEx(this->mutex_, qwTimeout);
|
||||
}
|
||||
|
||||
bool ConditionVariableImpl::WaitForSignalNsEx(const std::shared_ptr<UnixConditionMutex> &pMutex,
|
||||
AuUInt64 qwTimeout)
|
||||
{
|
||||
auto mutex = reinterpret_cast<pthread_mutex_t*>(pMutex->GetOSHandle());
|
||||
|
||||
if (gRuntimeRunLevel >= 5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
if (qwTimeout == 0)
|
||||
{
|
||||
int ret {};
|
||||
do
|
||||
@ -65,7 +72,7 @@ namespace Aurora::Threading::Primitives
|
||||
else
|
||||
{
|
||||
struct timespec tspec;
|
||||
Time::auabsns2ts(&tspec, AuTime::CurrentClockNS() + qwTimeout);
|
||||
Time::monoabsns2ts(&tspec, AuTime::SteadyClockNS() + qwTimeout);
|
||||
|
||||
int ret {};
|
||||
|
||||
|
@ -8,23 +8,33 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(_AURUNTIME_GENERICCV)
|
||||
#include "AuConditionMutex.Unix.hpp"
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
struct ConditionVariableImpl : IConditionVariable
|
||||
struct ConditionVariableImpl final : IConditionVariable
|
||||
{
|
||||
ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex);
|
||||
~ConditionVariableImpl();
|
||||
|
||||
AuSPtr<IConditionMutex> GetMutex() override;
|
||||
bool WaitForSignal(AuUInt32 timeout) override;
|
||||
bool WaitForSignalNS(AuUInt64 timeout) override;
|
||||
bool WaitForSignalNsEx(const std::shared_ptr<UnixConditionMutex> &pMutex, AuUInt64 timeout);
|
||||
bool WaitForSignalNS(AuUInt64 qwTimeout) override;
|
||||
void Signal() override;
|
||||
void Broadcast() override;
|
||||
|
||||
// TODO: ...
|
||||
pthread_cond_t pthreadCv_;
|
||||
private:
|
||||
AuSPtr<IConditionMutexEx> mutex_;
|
||||
AuSPtr<UnixConditionMutex> mutex_;
|
||||
};
|
||||
|
||||
struct CondVarDummy : IConditionVariable
|
||||
{
|
||||
pthread_cond_t pthreadCv_;
|
||||
};
|
||||
|
||||
static const auto kSizeOfDummyCondVar = sizeof(CondVarDummy);
|
||||
|
||||
}
|
||||
#endif
|
@ -17,6 +17,9 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
#define barrier() __asm__ __volatile__("sfence": : :"memory")
|
||||
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
static int futex(uint32_t *uaddr, int futex_op, uint32_t val,
|
||||
const struct timespec *timeout,
|
||||
uint32_t *uaddr2, uint32_t val3)
|
||||
@ -24,26 +27,26 @@ namespace Aurora::Threading::Primitives
|
||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
}
|
||||
|
||||
static int futex_wait(uint32_t *addr, uint32_t expected)
|
||||
static int futex_wait(volatile uint32_t *addr, uint32_t expected)
|
||||
{
|
||||
return futex(addr, FUTEX_WAIT, expected, 0, 0, 0);
|
||||
return futex((uint32_t *)addr, FUTEX_WAIT, expected, 0, 0, 0);
|
||||
}
|
||||
|
||||
static int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
||||
static int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout)
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
return futex(addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
||||
return futex((uint32_t *)addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return futex(addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
||||
return futex((uint32_t *)addr, FUTEX_WAIT, expected, timeout, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int futex_wake(uint32_t *addr, uint32_t nthreads)
|
||||
static int futex_wake(volatile uint32_t *addr, uint32_t nthreads)
|
||||
{
|
||||
return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
||||
return futex((uint32_t *)addr, FUTEX_WAKE, nthreads, 0, 0, 0);
|
||||
}
|
||||
|
||||
MutexImpl::MutexImpl()
|
||||
@ -70,8 +73,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
auto old = this->value_;
|
||||
return (old == 0 && AuAtomicCompareExchange<AuUInt32>(&this->value_, 1, old) == old);
|
||||
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,29 +92,36 @@ namespace Aurora::Threading::Primitives
|
||||
return true;
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->dwSleeping_, 1u);
|
||||
|
||||
//redundant: 8.2.3.8
|
||||
//barrier();
|
||||
|
||||
struct timespec tspec;
|
||||
if (uTimeout != 0)
|
||||
{
|
||||
uStart = AuTime::SteadyClockNS();
|
||||
uEnd = uStart + uTimeout;
|
||||
|
||||
Time::auabsns2ts(&tspec, uEnd);
|
||||
Time::monoabsns2ts(&tspec, uEnd);
|
||||
}
|
||||
|
||||
auto state = this->value_;
|
||||
while (!(state == 0 && AuAtomicCompareExchange<AuUInt32>(&this->value_, 1, state) == state))
|
||||
auto state = this->state_;
|
||||
while (!(state == 0 &&
|
||||
AuAtomicCompareExchange<AuUInt32>(&this->state_, 1, state) == state))
|
||||
{
|
||||
if (uTimeout != 0)
|
||||
{
|
||||
if (Time::SteadyClockNS() >= uEnd)
|
||||
{
|
||||
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret {};
|
||||
do
|
||||
{
|
||||
ret = futex_wait(&this->value_, state, &tspec);
|
||||
ret = futex_wait(&this->state_, state, &tspec);
|
||||
}
|
||||
while (ret == EINTR);
|
||||
}
|
||||
@ -123,7 +132,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
do
|
||||
{
|
||||
if ((ret = futex_wait(&this->value_, state)) == 0)
|
||||
if ((ret = futex_wait(&this->state_, state)) == 0)
|
||||
{
|
||||
bStatus = true;
|
||||
break;
|
||||
@ -141,13 +150,14 @@ namespace Aurora::Threading::Primitives
|
||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
||||
}
|
||||
|
||||
state = this->value_;
|
||||
state = this->state_;
|
||||
}
|
||||
|
||||
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MutexImpl::Lock()
|
||||
void MutexImpl::SlowLock()
|
||||
{
|
||||
auto status = LockMS(0);
|
||||
SysAssert(status, "Couldn't lock mutex");
|
||||
@ -155,16 +165,20 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
void MutexImpl::Unlock()
|
||||
{
|
||||
this->value_ = 0;
|
||||
futex_wake(&this->value_, 1);
|
||||
__sync_lock_release(&this->state_);
|
||||
compilerReorderBarrier();
|
||||
if (this->dwSleeping_)
|
||||
{
|
||||
futex_wake(&this->state_, 1);
|
||||
}
|
||||
}
|
||||
|
||||
AUKN_SYM IWaitable *MutexNew()
|
||||
AUKN_SYM IHyperWaitable *MutexNew()
|
||||
{
|
||||
return _new MutexImpl();
|
||||
}
|
||||
|
||||
AUKN_SYM void MutexRelease(IWaitable *pMutex)
|
||||
AUKN_SYM void MutexRelease(IHyperWaitable *pMutex)
|
||||
{
|
||||
AuSafeDelete<MutexImpl *>(pMutex);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
struct MutexImpl : IWaitable
|
||||
struct MutexImpl : IHyperWaitable
|
||||
{
|
||||
MutexImpl();
|
||||
~MutexImpl();
|
||||
@ -17,12 +17,11 @@ namespace Aurora::Threading::Primitives
|
||||
bool HasOSHandle(AuMach &mach) override;
|
||||
bool TryLock() override;
|
||||
bool HasLockImplementation() override;
|
||||
void Lock() override;
|
||||
void SlowLock() override;
|
||||
bool LockMS(AuUInt64 timeout) override;
|
||||
bool LockNS(AuUInt64 timeout) override;
|
||||
void Unlock() override;
|
||||
|
||||
private:
|
||||
AuUInt32 value_ {};
|
||||
AuUInt32 dwSleeping_ {};
|
||||
};
|
||||
}
|
@ -14,6 +14,9 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
#define barrier() __asm__ __volatile__("sfence": : :"memory")
|
||||
#define compilerReorderBarrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
MutexImpl::MutexImpl()
|
||||
{
|
||||
pthread_condattr_t attr;
|
||||
@ -68,6 +71,8 @@ namespace Aurora::Threading::Primitives
|
||||
return true;
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->dwSleeping_, 1u);
|
||||
|
||||
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle());
|
||||
|
||||
struct timespec tspec;
|
||||
@ -76,7 +81,7 @@ namespace Aurora::Threading::Primitives
|
||||
uStart = AuTime::SteadyClockNS();
|
||||
uEnd = uStart + uTimeout;
|
||||
|
||||
Time::auabsns2ts(&tspec, uEnd);
|
||||
Time::monoabsns2ts(&tspec, uEnd);
|
||||
}
|
||||
|
||||
int ret {};
|
||||
@ -93,6 +98,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
if (Time::SteadyClockNS() >= uEnd)
|
||||
{
|
||||
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -120,6 +126,7 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
}
|
||||
|
||||
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -131,12 +138,20 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
void MutexImpl::Unlock()
|
||||
{
|
||||
__sync_lock_release(&this->value_);
|
||||
|
||||
compilerReorderBarrier();
|
||||
|
||||
if (this->dwSleeping_)
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
this->value_ = 0;
|
||||
{
|
||||
// Still required to barrier the mutually exclusive part of the condvar
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
//this->value_ = 0;
|
||||
}
|
||||
auto ret = ::pthread_cond_signal(&this->pthreadCv_);
|
||||
SysAssert(ret == 0, "Couldn't wake any mutex waiter");
|
||||
}
|
||||
auto ret = ::pthread_cond_signal(&this->pthreadCv_);
|
||||
SysAssert(ret == 0, "Couldn't wake any mutex waiter");
|
||||
}
|
||||
|
||||
AUKN_SYM IWaitable *MutexNew()
|
||||
|
@ -26,8 +26,8 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
private:
|
||||
AuInt32 value_ {};
|
||||
pthread_cond_t pthreadCv_ {};
|
||||
UnixConditionMutex mutex_;
|
||||
AuUInt32 dwSleeping_ {};
|
||||
};
|
||||
}
|
@ -97,7 +97,7 @@ namespace Aurora::Threading::Primitives
|
||||
uStart = AuTime::SteadyClockNS();
|
||||
uEnd = uStart + uTimeout;
|
||||
|
||||
Time::auabsns2ts(&tspec, uEnd);
|
||||
Time::monoabsns2ts(&tspec, uEnd);
|
||||
}
|
||||
|
||||
auto old = this->value_;
|
||||
|
@ -78,7 +78,7 @@ namespace Aurora::Threading::Primitives
|
||||
uStart = AuTime::SteadyClockNS();
|
||||
uEnd = uStart + uTimeout;
|
||||
|
||||
Time::auabsns2ts(&tspec, uEnd);
|
||||
Time::monoabsns2ts(&tspec, uEnd);
|
||||
}
|
||||
|
||||
while (!this->TryLock())
|
||||
|
@ -457,9 +457,11 @@ namespace Aurora::Threading::Threads
|
||||
auto ret = SpawnThread([this]()
|
||||
{
|
||||
while ((!this->handle_) ||
|
||||
#if defined(INVALID_HANDLE_VALUE)
|
||||
#if defined(INVALID_HANDLE_VALUE)
|
||||
(this->handle_ == INVALID_HANDLE_VALUE)
|
||||
#endif
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
AuThreading::ContextYield();
|
||||
@ -693,6 +695,11 @@ namespace Aurora::Threading::Threads
|
||||
|
||||
#elif defined(AURORA_HAS_PTHREADS)
|
||||
|
||||
if (!this->handle_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_setname_np(this->handle_, this->name_.c_str());
|
||||
|
||||
#endif
|
||||
@ -1022,7 +1029,12 @@ namespace Aurora::Threading::Threads
|
||||
return;
|
||||
|
||||
#elif defined(AURORA_HAS_PTHREADS)
|
||||
|
||||
|
||||
if (!this->handle_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto mask2 = mask.And(this->throttleMask_);
|
||||
|
||||
if (mask2.CpuBitCount() == 0)
|
||||
|
@ -63,6 +63,10 @@ using high_res_clock = std::chrono::high_resolution_clock;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
using sys_clock = std::chrono::system_clock;
|
||||
using steady_clock = std::chrono::steady_clock;
|
||||
|
||||
|
@ -84,12 +84,19 @@ namespace Aurora::Time
|
||||
ts->tv_nsec = remainderNS;
|
||||
}
|
||||
|
||||
static void monoabsns2ts(struct timespec *ts, unsigned long long ns)
|
||||
{
|
||||
auto remainderNS = (AuUInt64)ns % (AuUInt64)1'000'000'000;
|
||||
ts->tv_sec = ns / 1'000'000'000ull;
|
||||
ts->tv_nsec = remainderNS;
|
||||
}
|
||||
|
||||
static void auabsns2ts(struct timespec *ts, unsigned long long ns)
|
||||
{
|
||||
auto baseNS = ns + AuMSToNS<AuUInt64>(999'080'100'000);
|
||||
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
||||
|
||||
ts->tv_sec += baseNS / 1'000'000'000ull;
|
||||
ts->tv_sec = baseNS / 1'000'000'000ull;
|
||||
ts->tv_nsec = remainderNS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user