[+] WIP internal IO improvements (read: hacks) for Linux + bool IProcess::HasExited()
This commit is contained in:
parent
06f54968cd
commit
c5656a8843
@ -30,9 +30,16 @@ namespace Aurora::Processes
|
||||
*
|
||||
*/
|
||||
virtual AuSPtr<IO::Loop::ILoopSource> AsLoopSource() = 0;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @return
|
||||
*/
|
||||
virtual bool HasExited() = 0;
|
||||
|
||||
/**
|
||||
* @brief returns the exit code of the process should we outlive them
|
||||
* @brief returns the exit code of the process should we outlive them.
|
||||
* undefined if the process has yet to exit.
|
||||
* @return
|
||||
*/
|
||||
virtual AuSInt GetExitCode() = 0;
|
||||
|
@ -93,8 +93,19 @@ namespace Aurora::IO::FS
|
||||
return Loop::ELoopSource::eSourceAIO;
|
||||
}
|
||||
|
||||
LinuxAsyncFileTransaction::LinuxAsyncFileTransaction(AuSPtr<ProcessBlock> pProcessBlock) :
|
||||
pProcessBlock_(pProcessBlock)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LinuxAsyncFileTransaction::~LinuxAsyncFileTransaction()
|
||||
{
|
||||
if (this->pProcessBlock_)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pProcessBlock_->externalLock);
|
||||
AuTryRemove(this->pProcessBlock_->submits, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxAsyncFileStream::Init(const AuSPtr<IIOHandle> &handle)
|
||||
@ -102,9 +113,33 @@ namespace Aurora::IO::FS
|
||||
this->pHandle_ = handle;
|
||||
}
|
||||
|
||||
void LinuxAsyncFileStream::MakeProcess(Processes::IProcess *pProcess)
|
||||
{
|
||||
this->pProcessBlock_ = AuMakeSharedThrow<ProcessBlock>();
|
||||
this->pProcessBlock_->pProcess = pProcess;
|
||||
}
|
||||
|
||||
void LinuxAsyncFileStream::CheckProcess()
|
||||
{
|
||||
if (this->pProcessBlock_)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pProcessBlock_->externalLock);
|
||||
if (this->pProcessBlock_->pProcess &&
|
||||
this->pProcessBlock_->pProcess->HasExited())
|
||||
{
|
||||
this->pProcessBlock_->pProcess = nullptr;
|
||||
this->pProcessBlock_->bDead = true;
|
||||
for (auto &pSubmittable : this->pProcessBlock_->submits)
|
||||
{
|
||||
pSubmittable->LIOS_Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AuSPtr<IAsyncTransaction> LinuxAsyncFileStream::NewTransaction()
|
||||
{
|
||||
auto shared = AuMakeShared<LinuxAsyncFileTransaction>();
|
||||
auto shared = AuMakeShared<LinuxAsyncFileTransaction>(this->pProcessBlock_);
|
||||
if (!shared)
|
||||
{
|
||||
return {};
|
||||
@ -115,6 +150,16 @@ namespace Aurora::IO::FS
|
||||
return {};
|
||||
}
|
||||
|
||||
if (this->pProcessBlock_)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pProcessBlock_->externalLock);
|
||||
if (!AuTryInsert(this->pProcessBlock_->submits, shared.get()))
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return shared;
|
||||
}
|
||||
|
||||
@ -160,6 +205,13 @@ namespace Aurora::IO::FS
|
||||
}
|
||||
}
|
||||
|
||||
if (this->pProcessBlock_ &&
|
||||
this->pProcessBlock_->bDead)
|
||||
{
|
||||
parameters.outVariable = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!PosixSetOffset(fd, offset))
|
||||
{
|
||||
return false;
|
||||
@ -194,6 +246,12 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->pProcessBlock_ &&
|
||||
this->pProcessBlock_->bDead)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AuUInt32 read;
|
||||
if (!PosixWrite(fd, parameters.ptr, parameters.length, &read))
|
||||
{
|
||||
@ -205,6 +263,10 @@ namespace Aurora::IO::FS
|
||||
|
||||
bool LinuxAsyncFileTransaction::Init(const AuSPtr<IIOHandle> &handle)
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this->pHandle_ = handle;
|
||||
this->loopSource_ = AuMakeShared<LinuxAsyncFileTransactionLoopSource>(AuSharedFromThis());
|
||||
return bool(this->loopSource_);
|
||||
@ -263,6 +325,13 @@ namespace Aurora::IO::FS
|
||||
}
|
||||
}
|
||||
|
||||
if (this->pProcessBlock_ &&
|
||||
this->pProcessBlock_->bDead)
|
||||
{
|
||||
LIOS_SendProcess(0, false, errno);
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += this->uBaseOffset;
|
||||
|
||||
if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(IPC_PIPE)))
|
||||
@ -320,6 +389,13 @@ namespace Aurora::IO::FS
|
||||
LIOS_Init(AuSharedFromThis());
|
||||
SetMemory(memoryView);
|
||||
|
||||
if (this->pProcessBlock_ &&
|
||||
this->pProcessBlock_->bDead)
|
||||
{
|
||||
LIOS_SendProcess(0, false, errno);
|
||||
return true;
|
||||
}
|
||||
|
||||
offset += this->uBaseOffset;
|
||||
|
||||
if (!UNIX::LinuxOverlappedSubmitWrite(fd, offset, this, this->loopSource_.get()))
|
||||
@ -447,7 +523,7 @@ namespace Aurora::IO::FS
|
||||
|
||||
AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock)
|
||||
{
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
auto pHandle = AuIO::IOHandleShared();
|
||||
if (!pHandle)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
|
@ -17,6 +17,14 @@ namespace Aurora::IO::FS
|
||||
struct LinuxAsyncFileTransaction;
|
||||
struct LinuxAsyncFileTransactionLoopSource;
|
||||
|
||||
struct ProcessBlock
|
||||
{
|
||||
AuMutex externalLock;
|
||||
Processes::IProcess *pProcess;
|
||||
AuList<Aurora::IO::UNIX::ASubmittable *> submits;
|
||||
bool bDead {};
|
||||
};
|
||||
|
||||
struct LinuxAsyncFileStream : IAsyncFileStream
|
||||
{
|
||||
AuSPtr<IAsyncTransaction> NewTransaction() override;
|
||||
@ -26,15 +34,19 @@ namespace Aurora::IO::FS
|
||||
|
||||
void Init(const AuSPtr<IIOHandle> &handle);
|
||||
|
||||
AuSPtr<IIOHandle> GetHandle();
|
||||
void CheckProcess();
|
||||
void MakeProcess(Processes::IProcess *pProcess);
|
||||
|
||||
AuSPtr<IIOHandle> GetHandle();
|
||||
private:
|
||||
AuSPtr<ProcessBlock> pProcessBlock_;
|
||||
AuSPtr<IIOHandle> pHandle_;
|
||||
};
|
||||
|
||||
|
||||
struct LinuxAsyncFileTransaction : IAsyncTransaction, AuEnableSharedFromThis<LinuxAsyncFileTransaction>, Aurora::IO::UNIX::ASubmittable
|
||||
{
|
||||
LinuxAsyncFileTransaction(AuSPtr<ProcessBlock> pProcessBlock);
|
||||
~LinuxAsyncFileTransaction();
|
||||
|
||||
bool Init(const AuSPtr<IIOHandle> &handle);
|
||||
|
@ -362,6 +362,8 @@ namespace Aurora::IO::UNIX
|
||||
return false;
|
||||
}
|
||||
|
||||
context->abortContext = io->context;
|
||||
|
||||
iocb &submit = context->GetIOCB();
|
||||
submit.aio_data = context->GetData();
|
||||
submit.aio_lio_opcode = op;
|
||||
@ -400,7 +402,7 @@ namespace Aurora::IO::UNIX
|
||||
}
|
||||
|
||||
iocb &submit = context->GetIOCB();
|
||||
if (io_cancel(io->context, &submit, &result) != 0)
|
||||
if (io_cancel(context->abortContext, &submit, &result) != 0)
|
||||
{
|
||||
if (errno == EAGAIN) // The iocb specified was not canceled
|
||||
{
|
||||
@ -428,7 +430,16 @@ namespace Aurora::IO::UNIX
|
||||
}
|
||||
|
||||
context->LIOS_Reset();
|
||||
context->LIOS_SendProcess(bytesTransacted, bError, iErrNo);
|
||||
|
||||
// if we're going out of our way to somewhat support cross-thread aborts, this doesnt matter
|
||||
// let the higher level api filter the abort/reset call
|
||||
// we're going to be more sorry if we miss a reset/proces-death/eos callback than we allow the api to perform cross-thread aborts
|
||||
#if 0
|
||||
if (context->abortContext == io->context)
|
||||
{
|
||||
#endif
|
||||
context->LIOS_SendProcess(bytesTransacted, bError, iErrNo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ namespace Aurora::IO::UNIX
|
||||
AuUInt64 offset2 {};
|
||||
int fd2 {};
|
||||
AuLoop::ILSEvent *optEvent2 {};
|
||||
aio_context_t abortContext {};
|
||||
|
||||
private:
|
||||
AuUInt64 dataPtr_ {};
|
||||
|
@ -19,7 +19,7 @@ namespace Aurora::Processes
|
||||
bool TermWinEnumProcesses();
|
||||
|
||||
bool TryKill() override;
|
||||
bool HasExited();
|
||||
bool HasExited() override;
|
||||
|
||||
AuUInt GetProcessId() override;
|
||||
|
||||
|
@ -125,9 +125,15 @@ namespace Aurora::Processes
|
||||
return this->pidt_;
|
||||
}
|
||||
|
||||
bool ProcessImpl::HasExited()
|
||||
{
|
||||
return this->bHasExited;
|
||||
}
|
||||
|
||||
void ProcessImpl::ByeLol(AuSInt code)
|
||||
{
|
||||
this->exitCode_ = code;
|
||||
this->bHasExited = true;
|
||||
|
||||
if (this->finished_)
|
||||
{
|
||||
@ -138,6 +144,16 @@ namespace Aurora::Processes
|
||||
{
|
||||
this->loopSource_->Set();
|
||||
}
|
||||
|
||||
if (this->fsStream_)
|
||||
{
|
||||
this->fsStream_->CheckProcess();
|
||||
}
|
||||
|
||||
if (this->fsErrorStream_)
|
||||
{
|
||||
this->fsErrorStream_->CheckProcess();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessImpl::ShutdownPipes()
|
||||
@ -438,6 +454,7 @@ namespace Aurora::Processes
|
||||
this->fsHandle_->InitFromPairMove(this->pipeStdOut_[0] == -1 ? AuOptionalEx<AuUInt64> {} : AuOptionalEx<AuUInt64> { (AuUInt64)this->pipeStdOut_[0] } ,
|
||||
this->pipeStdIn_[1] == -1 ? AuOptionalEx<AuUInt64> {} : AuOptionalEx<AuUInt64> { (AuUInt64)this->pipeStdIn_[1] });
|
||||
this->fsStream_->Init(this->fsHandle_);
|
||||
this->fsStream_->MakeProcess(this);
|
||||
}
|
||||
|
||||
if (this->startup_.fwdErr == EStreamForward::eAsyncPipe)
|
||||
@ -456,6 +473,7 @@ namespace Aurora::Processes
|
||||
|
||||
this->fsErrorHandle_->InitFromPairMove(this->pipeStdErr_[0] == -1 ? AuOptionalEx<AuUInt64> {} : AuOptionalEx<AuUInt64> { (AuUInt64)this->pipeStdErr_[0] }, {});
|
||||
this->fsErrorStream_->Init(this->fsErrorHandle_);
|
||||
this->fsErrorStream_->MakeProcess(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -32,6 +32,7 @@ namespace Aurora::Processes
|
||||
|
||||
void ShutdownPipes();
|
||||
|
||||
bool HasExited() override;
|
||||
bool TryKill() override;
|
||||
bool Terminate() override;
|
||||
AuSPtr<Threading::IWaitable> AsWaitable() override;
|
||||
@ -89,6 +90,7 @@ namespace Aurora::Processes
|
||||
pid_t pidt_;
|
||||
bool alive_ {};
|
||||
|
||||
AuSInt exitCode_;
|
||||
AuSInt exitCode_ {};
|
||||
bool bHasExited {};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user