[*] Linux Progress... It compiles (APIs are out of date, subsystems are missing, and it doesn't link. Worse than being 5m behind)
This commit is contained in:
parent
d32b84edf4
commit
e25d8a65c8
@ -871,7 +871,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
if (!create)
|
if (!create)
|
||||||
{
|
{
|
||||||
threadState->threadObject = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
threadState->threadObject = AuThreads::ThreadShared(AuThreads::ThreadInfo(
|
||||||
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(&ThreadPool::Entrypoint, this, threadState->id)),
|
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(&ThreadPool::Entrypoint, this, threadState->id)),
|
||||||
AuThreads::IThreadVectorsFunctional::OnExit_t{}),
|
AuThreads::IThreadVectorsFunctional::OnExit_t{}),
|
||||||
gRuntimeConfig.async.threadPoolDefaultStackSize
|
gRuntimeConfig.async.threadPoolDefaultStackSize
|
||||||
|
@ -25,17 +25,12 @@ namespace Aurora::Logging
|
|||||||
{
|
{
|
||||||
AUKN_SYM IBasicSink *NewStdSinkNew()
|
AUKN_SYM IBasicSink *NewStdSinkNew()
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
||||||
return Sinks::NewStdSinkNew();
|
return Sinks::NewStdSinkNew();
|
||||||
#endif
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM void NewStdSinkRelease(IBasicSink *sink)
|
AUKN_SYM void NewStdSinkRelease(IBasicSink *sink)
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
||||||
Sinks::NewStdSinkRelease(sink);
|
Sinks::NewStdSinkRelease(sink);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM IBasicSink *NewOSEventDirectorySinkNew()
|
AUKN_SYM IBasicSink *NewOSEventDirectorySinkNew()
|
||||||
@ -49,12 +44,17 @@ namespace Aurora::Logging
|
|||||||
|
|
||||||
AUKN_SYM IBasicSink *NewDebugLoggerNew()
|
AUKN_SYM IBasicSink *NewDebugLoggerNew()
|
||||||
{
|
{
|
||||||
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
return Sinks::NewDebugLoggerNew();
|
return Sinks::NewDebugLoggerNew();
|
||||||
|
#endif
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM void NewDebugLoggerRelease(IBasicSink *sink)
|
AUKN_SYM void NewDebugLoggerRelease(IBasicSink *sink)
|
||||||
{
|
{
|
||||||
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
return Sinks::NewDebugLoggerRelease(sink);
|
return Sinks::NewDebugLoggerRelease(sink);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,4 +91,20 @@ namespace Aurora::Loop
|
|||||||
{
|
{
|
||||||
return ELoopSource::eSourceEvent;
|
return ELoopSource::eSourceEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<ILSEvent> NewLSEvent()
|
||||||
|
{
|
||||||
|
auto event = AuMakeShared<LSEvent>();
|
||||||
|
if (!event)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event->HasValidHandle())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,11 +10,11 @@
|
|||||||
namespace Aurora::Loop
|
namespace Aurora::Loop
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void IsSignaledFromNonblockingImpl(ILoopSourceEx *source, T * that, bool(T *::IsSignaledNonblocking)())
|
inline bool IsSignaledFromNonblockingImpl(ILoopSourceEx *source, T * that, bool(T::*IsSignaledNonblocking)())
|
||||||
{
|
{
|
||||||
bool val {};
|
bool val {};
|
||||||
source->OnPresleep();
|
source->OnPresleep();
|
||||||
val = ((that).*(IsSignaledNonblocking))();
|
val = ((that)->*(IsSignaledNonblocking))();
|
||||||
source->OnFinishSleep();
|
source->OnFinishSleep();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,67 @@
|
|||||||
***/
|
***/
|
||||||
#include <Source/RuntimeInternal.hpp>
|
#include <Source/RuntimeInternal.hpp>
|
||||||
#include "LSSemaphore.hpp"
|
#include "LSSemaphore.hpp"
|
||||||
|
#include "LSFromFdNonblocking.hpp"
|
||||||
|
|
||||||
namespace Aurora::Loop
|
namespace Aurora::Loop
|
||||||
{
|
{
|
||||||
|
LSSemaphore::LSSemaphore(AuUInt32 initialCount)
|
||||||
|
{
|
||||||
|
Init(initialCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSSemaphore::Init(AuUInt32 initialCount)
|
||||||
|
{
|
||||||
|
handle = eventfd(initialCount, EFD_SEMAPHORE | EFD_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSSemaphore::IsSignaledNonblocking()
|
||||||
|
{
|
||||||
|
AuUInt64 oldSemaphoreValue {};
|
||||||
|
return read(this->handle, &oldSemaphoreValue, sizeof(oldSemaphoreValue)) == 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSSemaphore::AddOne()
|
||||||
|
{
|
||||||
|
AuUInt64 plsNoOverflow {1};
|
||||||
|
|
||||||
|
if (write(this->handle, &plsNoOverflow, sizeof(plsNoOverflow)) != 8)
|
||||||
|
{
|
||||||
|
// todo push error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSSemaphore::OnTrigger(AuUInt handle)
|
||||||
|
{
|
||||||
|
return IsSignaledNonblocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LSSemaphore::IsSignaled()
|
||||||
|
{
|
||||||
|
return IsSignaledFromNonblockingImpl(this, this, &LSSemaphore::IsSignaledNonblocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
ELoopSource LSSemaphore::GetType()
|
||||||
|
{
|
||||||
|
return ELoopSource::eSourceSemaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuSPtr<ILSSemaphore> NewLSSemaphore(AuUInt32 initialCount)
|
||||||
|
{
|
||||||
|
auto semaphore = AuMakeShared<LSSemaphore>(initialCount);
|
||||||
|
if (!semaphore)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!semaphore->HasValidHandle())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return semaphore;
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
Author: Reece
|
Author: Reece
|
||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "LSHandle.hpp"
|
||||||
|
|
||||||
namespace Aurora::Loop
|
namespace Aurora::Loop
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,10 @@ namespace Aurora::Loop
|
|||||||
// network and file transactions independent from the loop queues
|
// network and file transactions independent from the loop queues
|
||||||
// As such, loop queues continue to be defined as a mechanism to merely
|
// As such, loop queues continue to be defined as a mechanism to merely
|
||||||
// wait, not dispatch/manage work
|
// wait, not dispatch/manage work
|
||||||
|
// Delegating mutex reads to a single io_submit would be a linux-specific
|
||||||
|
// kevent-non-reusable ThreadWorkerQueueShim hack
|
||||||
|
// ...it wouldn't make sense create another loop queue per thread concept
|
||||||
|
// outside of the async subsystem (not counting TLS overlapped io)
|
||||||
|
|
||||||
LoopQueue::LoopQueue()
|
LoopQueue::LoopQueue()
|
||||||
{
|
{
|
||||||
@ -82,7 +86,7 @@ namespace Aurora::Loop
|
|||||||
|
|
||||||
bool LoopQueue::Commit()
|
bool LoopQueue::Commit()
|
||||||
{
|
{
|
||||||
return {};
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoopQueue::IsSignaled()
|
bool LoopQueue::IsSignaled()
|
||||||
|
@ -9,6 +9,6 @@
|
|||||||
|
|
||||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
#include "LoopQueue.NT.hpp"
|
#include "LoopQueue.NT.hpp"
|
||||||
#elif defined(AURORA_PLATFORM_LINX)
|
#elif defined(AURORA_PLATFORM_LINUX)
|
||||||
#include "LoopQueue.Linux.hpp"
|
#include "LoopQueue.Linux.hpp"
|
||||||
#endif
|
#endif
|
@ -73,7 +73,7 @@ namespace Aurora::Loop
|
|||||||
FD_SET(read, &readSet);
|
FD_SET(read, &readSet);
|
||||||
FD_SET(write, &writeSet);
|
FD_SET(write, &writeSet);
|
||||||
|
|
||||||
auto active = select(handle + 1, read != -1 ? &readSet : NULL, write != -1 ? &writeSet : NULL, NULL, &tv);
|
auto active = select(AuMax(read, write) + 1, read != -1 ? &readSet : NULL, write != -1 ? &writeSet : NULL, NULL, &tv);
|
||||||
if (active == -1)
|
if (active == -1)
|
||||||
{
|
{
|
||||||
// todo push error
|
// todo push error
|
||||||
|
@ -11,7 +11,7 @@ namespace Aurora::Loop
|
|||||||
{
|
{
|
||||||
struct WaitSingleGeneric : WaitSingleBase
|
struct WaitSingleGeneric : WaitSingleBase
|
||||||
{
|
{
|
||||||
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &read _OPT_WRITE) override;
|
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &read _OPT_WRITE_REF) override;
|
||||||
virtual bool WaitForOne(AuUInt handle _OPT_WRITE) override;
|
virtual bool WaitForOne(AuUInt handle _OPT_WRITE) override;
|
||||||
virtual void OnPresleep() override;
|
virtual void OnPresleep() override;
|
||||||
virtual void OnFinishSleep() override;
|
virtual void OnFinishSleep() override;
|
||||||
|
@ -14,6 +14,7 @@ namespace Aurora::Loop
|
|||||||
{
|
{
|
||||||
bool val {};
|
bool val {};
|
||||||
AuUInt one {};
|
AuUInt one {};
|
||||||
|
AuUInt two {};
|
||||||
this->OnPresleep();
|
this->OnPresleep();
|
||||||
|
|
||||||
if (this->Singular())
|
if (this->Singular())
|
||||||
@ -33,8 +34,16 @@ namespace Aurora::Loop
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
auto handles = this->GetHandles();
|
auto handles = this->GetHandles();
|
||||||
val = WaitForAtleastOne(handles, one);
|
auto handlesRw = this->GetWriteHandles();
|
||||||
|
val = this->WaitForAtleastOne(handles, handlesRw, one, two);
|
||||||
|
if (one == -1) one = two;
|
||||||
|
#else
|
||||||
|
auto handles = this->GetHandles();
|
||||||
|
val = this->WaitForAtleastOne(handles, one);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
val = this->OnTrigger(one);
|
val = this->OnTrigger(one);
|
||||||
|
@ -13,9 +13,11 @@ namespace Aurora::Loop
|
|||||||
{
|
{
|
||||||
|
|
||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
#define _OPT_WRITE , AuUInt &write
|
#define _OPT_WRITE , AuUInt write
|
||||||
|
#define _OPT_WRITE_REF , AuUInt &write
|
||||||
#else
|
#else
|
||||||
#define _OPT_WRITE
|
#define _OPT_WRITE
|
||||||
|
#define _OPT_WRITE_REF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
@ -29,7 +31,7 @@ namespace Aurora::Loop
|
|||||||
{
|
{
|
||||||
bool IsSignaled() override;
|
bool IsSignaled() override;
|
||||||
|
|
||||||
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &one _OPT_WRITE) = 0;
|
virtual bool WaitForAtleastOne(const AuList<AuUInt> &handles _OPT_WRITE_ARRAY, AuUInt &one _OPT_WRITE_REF) = 0;
|
||||||
virtual bool WaitForOne(AuUInt handle _OPT_WRITE) = 0;
|
virtual bool WaitForOne(AuUInt handle _OPT_WRITE) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,327 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: Process.Linux.cpp
|
|
||||||
Date: 2021-6-12
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#include <RuntimeInternal.hpp>
|
|
||||||
#include "Processes.hpp"
|
|
||||||
#include "Process.Linux.hpp"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <Source/Threading/Primitives/Semaphore.Unix.hpp>
|
|
||||||
|
|
||||||
static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
|
||||||
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sys_pidfd_open(pid_t pid, unsigned int flags)
|
|
||||||
{
|
|
||||||
return syscall(__NR_pidfd_open, pid, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef P_PIDFD
|
|
||||||
#define P_PIDFD 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Aurora::Processes
|
|
||||||
{
|
|
||||||
class ProcessImpl : public IProcess
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ProcessImpl(AuString cmd, AuList<AuString> args);
|
|
||||||
~ProcessImpl();
|
|
||||||
|
|
||||||
void ShutdownPipes();
|
|
||||||
|
|
||||||
bool TryKill() override;
|
|
||||||
bool Terminate() override;
|
|
||||||
AuSPtr<Aurora::Threading::IWaitable> AsWaitable() override;
|
|
||||||
|
|
||||||
AuSInt GetExitCode() override;
|
|
||||||
|
|
||||||
bool Read(bool error, void *buffer, AuUInt32 &len) override;
|
|
||||||
bool Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock) override;
|
|
||||||
|
|
||||||
bool Write(const void *buffer, AuUInt32 len) override;
|
|
||||||
|
|
||||||
bool Start(enum ESpawnType type, bool fwdOut, bool fwdErr, bool fwdIn) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
int pipeStdOut_[2]{};
|
|
||||||
int pipeStdErr_[2]{};
|
|
||||||
int pipeStdIn_ [2]{};
|
|
||||||
|
|
||||||
AuString module_;
|
|
||||||
ESpawnType type_;
|
|
||||||
|
|
||||||
AuList<AuString> args_;
|
|
||||||
AuList<const char *> cargs_;
|
|
||||||
|
|
||||||
AuString windows_;
|
|
||||||
|
|
||||||
Threading::Threads::ThreadUnique_t thread_;
|
|
||||||
std::atomic<int> handle_;
|
|
||||||
|
|
||||||
AuSInt exitCode_;
|
|
||||||
};
|
|
||||||
|
|
||||||
ProcessImpl::ProcessImpl(AuString cmd, AuList<AuString> args) : module_(cmd), args_(args)
|
|
||||||
{
|
|
||||||
this->args_.insert(this->args_.begin(), cmd);
|
|
||||||
|
|
||||||
for (auto &arg : this->args_)
|
|
||||||
{
|
|
||||||
this->cargs_.push_back(arg.c_str());
|
|
||||||
this->windows_ += arg + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cargs_.push_back(nullptr);
|
|
||||||
this->windows_.resize(this->windows_.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessImpl::~ProcessImpl()
|
|
||||||
{
|
|
||||||
if (this->type_ == ESpawnType::eSpawnChildProcessWorker)
|
|
||||||
{
|
|
||||||
TryKill();
|
|
||||||
Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->handle_)
|
|
||||||
{
|
|
||||||
if (this->type_ == ESpawnType::eSpawnThreadLeader)
|
|
||||||
{
|
|
||||||
sys_pidfd_send_signal(this->handle_, SIGCONT, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->thread_)
|
|
||||||
{
|
|
||||||
this->thread_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto handle = this->handle_.exchange(0))
|
|
||||||
{
|
|
||||||
close(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShutdownPipes();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessImpl::ShutdownPipes()
|
|
||||||
{
|
|
||||||
if (auto fd = std::exchange(pipeStdErr_[0], {})) close(fd);
|
|
||||||
if (auto fd = std::exchange(pipeStdErr_[1], {})) close(fd);
|
|
||||||
if (auto fd = std::exchange(pipeStdOut_[0], {})) close(fd);
|
|
||||||
if (auto fd = std::exchange(pipeStdOut_[1], {})) close(fd);
|
|
||||||
if (auto fd = std::exchange(pipeStdIn_[0], {})) close(fd);
|
|
||||||
if (auto fd = std::exchange(pipeStdIn_[1], {})) close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::TryKill()
|
|
||||||
{
|
|
||||||
if (this->handle_)
|
|
||||||
{
|
|
||||||
return sys_pidfd_send_signal(this->handle_, SIGTERM, NULL, 0) == 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::Terminate()
|
|
||||||
{
|
|
||||||
if (this->handle_)
|
|
||||||
{
|
|
||||||
sys_pidfd_send_signal(this->handle_, SIGKILL, NULL, 0);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<Aurora::Threading::IWaitable> ProcessImpl::AsWaitable()
|
|
||||||
{
|
|
||||||
if (!this->thread_) return nullptr;
|
|
||||||
return this->thread_->AsWaitable();
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSInt ProcessImpl::GetExitCode()
|
|
||||||
{
|
|
||||||
return this->exitCode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int aurora_sys_waitid(int which, pid_t pid, siginfo_t *info, int options,
|
|
||||||
struct rusage *ru)
|
|
||||||
{
|
|
||||||
return syscall(__NR_waitid, which, pid, info, options, ru);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::Read(bool error, void *buffer, AuUInt32 &len)
|
|
||||||
{
|
|
||||||
return Read(buffer, len, error, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::Read(void *buffer, AuUInt32 &len, bool errorStream, bool nonblock)
|
|
||||||
{
|
|
||||||
len = 0;
|
|
||||||
auto handle = errorStream ? pipeStdErr_[0] : pipeStdOut_[0];
|
|
||||||
if (handle < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto control = fcntl(fd, F_GETFL);
|
|
||||||
auto ref = control;
|
|
||||||
if (nonblock)
|
|
||||||
{
|
|
||||||
control |= O_NONBLOCK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
control &= ~O_NONBLOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref != control)
|
|
||||||
{
|
|
||||||
fcntl(fd, F_SETFL, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tmp = read(handle, buffer, len);
|
|
||||||
if (tmp < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = tmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::Write(const void *buffer, AuUInt32 len)
|
|
||||||
{
|
|
||||||
auto handle = pipeStdIn_[1];
|
|
||||||
if (!handle) return false;
|
|
||||||
return write(handle, buffer, len) == len;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessImpl::Start(enum ESpawnType type, bool fwdOut, bool fwdErr, bool fwdIn)
|
|
||||||
{
|
|
||||||
this->exitCode_ = 0x10110100;
|
|
||||||
this->type_ = type;
|
|
||||||
|
|
||||||
if (type == ESpawnType::eSpawnAtomicOvermap)
|
|
||||||
{
|
|
||||||
execv(this->module_.c_str(), (char *const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
|
||||||
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->module_, this->windows_);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwdOut)
|
|
||||||
{
|
|
||||||
if (!pipe(pipeStdOut_))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwdErr)
|
|
||||||
{
|
|
||||||
if (!pipe(pipeStdErr_))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwdIn)
|
|
||||||
{
|
|
||||||
if (!pipe(pipeStdIn_))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Threading::Threads::AbstractThreadVectors handler;
|
|
||||||
|
|
||||||
pid_t pid;
|
|
||||||
{
|
|
||||||
Threading::Primitives::Semaphore semaphore;
|
|
||||||
pid = fork();
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
semaphore.Lock();
|
|
||||||
|
|
||||||
if (fwdIn)
|
|
||||||
{
|
|
||||||
dup2(pipeStdIn_[0], STDIN_FILENO);
|
|
||||||
close(std::exchange(pipeStdIn_[0], 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwdErr)
|
|
||||||
{
|
|
||||||
dup2(pipeStdErr_[1], STDERR_FILENO);
|
|
||||||
close(std::exchange(pipeStdErr_[1], 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwdOut)
|
|
||||||
{
|
|
||||||
dup2(pipeStdOut_[1], STDOUT_FILENO);
|
|
||||||
close(std::exchange(pipeStdOut_[1], 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != ESpawnType::eSpawnChildProcessWorker)
|
|
||||||
{
|
|
||||||
setsid();
|
|
||||||
}
|
|
||||||
|
|
||||||
execv(this->module_.c_str(), (char * const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
|
||||||
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->module_, this->windows_);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (pid < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->handle_ = sys_pidfd_open(pid, 0);
|
|
||||||
semaphore.Unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.DoRun = [=](Threading::Threads::IAuroraThread *)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
// TODO: experimental (and requires kernel 5.3+)
|
|
||||||
siginfo_t info = {
|
|
||||||
.si_signo = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: vaildate response
|
|
||||||
aurora_sys_waitid(P_PIDFD, this->handle_, &info, WEXITED, NULL);
|
|
||||||
|
|
||||||
// TODO: confirm this works?!?
|
|
||||||
this->exitCode_ = info.si_status;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this->thread_ = Threading::Threads::ThreadUnique(handler);
|
|
||||||
if (!this->thread_) return false;
|
|
||||||
|
|
||||||
this->thread_->Run();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUKN_SYM IProcess *SpawnNew(const AuString &app, const AuList<AuString> &args)
|
|
||||||
{
|
|
||||||
return _new ProcessImpl(app, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
AUKN_SYM void SpawnRelease(IProcess *process)
|
|
||||||
{
|
|
||||||
SafeDelete<ProcessImpl *>(process);
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,8 @@ namespace Aurora::Processes
|
|||||||
{
|
{
|
||||||
ProcessImpl::ProcessImpl(const StartupParmaters ¶ms) : startup_(params)
|
ProcessImpl::ProcessImpl(const StartupParmaters ¶ms) : startup_(params)
|
||||||
{
|
{
|
||||||
|
AuIOFS::NormalizePath(this->startup_.process, this->startup_.process);
|
||||||
|
|
||||||
this->startup_.args.insert(startup_.args.begin(), startup_.process);
|
this->startup_.args.insert(startup_.args.begin(), startup_.process);
|
||||||
|
|
||||||
// ehhhh https://github.com/tritao/WindowsSDK/blob/07983c7ba4f6861d15e23f195744c60c0c249ce0/SDKs/SourceDir/Windows%20Kits/10/Source/10.0.17763.0/ucrt/exec/cenvarg.cpp#L23
|
// ehhhh https://github.com/tritao/WindowsSDK/blob/07983c7ba4f6861d15e23f195744c60c0c249ce0/SDKs/SourceDir/Windows%20Kits/10/Source/10.0.17763.0/ucrt/exec/cenvarg.cpp#L23
|
||||||
@ -34,7 +36,10 @@ namespace Aurora::Processes
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->cargs_.push_back(nullptr);
|
this->cargs_.push_back(nullptr);
|
||||||
this->windowsCli_.resize(this->windowsCli_.size() - 1);
|
if (windowsCli_.size())
|
||||||
|
{
|
||||||
|
this->windowsCli_.resize(this->windowsCli_.size() - 1);
|
||||||
|
}
|
||||||
this->type_ = params.type;
|
this->type_ = params.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +305,7 @@ namespace Aurora::Processes
|
|||||||
startupInfo.hStdOutput = pipeStdOutWrite_;
|
startupInfo.hStdOutput = pipeStdOutWrite_;
|
||||||
startupInfo.dwFlags |= (inheritHandles ? STARTF_USESTDHANDLES : 0);
|
startupInfo.dwFlags |= (inheritHandles ? STARTF_USESTDHANDLES : 0);
|
||||||
|
|
||||||
auto result = CreateProcessW(Locale::ConvertFromUTF8(AuIOFS::NormalizePathRet(this->startup_.process)).c_str(),
|
auto result = CreateProcessW(Locale::ConvertFromUTF8(this->startup_.process).c_str(),
|
||||||
Locale::ConvertFromUTF8(this->windowsCli_).data(),
|
Locale::ConvertFromUTF8(this->windowsCli_).data(),
|
||||||
NULL, NULL, inheritHandles,
|
NULL, NULL, inheritHandles,
|
||||||
this->startup_.noShowConsole ? CREATE_NO_WINDOW : NULL, // yea we can keep CREATE_NO_WINDOW on for non-console apps. its legal -> https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
|
this->startup_.noShowConsole ? CREATE_NO_WINDOW : NULL, // yea we can keep CREATE_NO_WINDOW on for non-console apps. its legal -> https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
|
||||||
|
384
Source/Processes/Process.Unix.cpp
Normal file
384
Source/Processes/Process.Unix.cpp
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: Process.Unix.cpp
|
||||||
|
File: Process.Linux.cpp
|
||||||
|
Date: 2021-6-12
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <RuntimeInternal.hpp>
|
||||||
|
#include "Processes.hpp"
|
||||||
|
#include "Process.Unix.hpp"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <Source/Threading/Primitives/Semaphore.Unix.hpp>
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
struct ProcessImpl;
|
||||||
|
|
||||||
|
struct ProcessImpl;
|
||||||
|
|
||||||
|
static AuThreadPrimitives::SpinLock gSpinLock;
|
||||||
|
static AuHashMap<pid_t, ProcessImpl *> gPidLookupMap;
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessImpl : public IProcess
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessImpl(const StartupParmaters ¶ms);
|
||||||
|
~ProcessImpl();
|
||||||
|
|
||||||
|
void ShutdownPipes();
|
||||||
|
|
||||||
|
bool TryKill() override;
|
||||||
|
bool Terminate() override;
|
||||||
|
AuSPtr<Aurora::Threading::IWaitable> AsWaitable() override;
|
||||||
|
|
||||||
|
AuSInt GetExitCode() override;
|
||||||
|
|
||||||
|
AuUInt GetProcessId() override;
|
||||||
|
|
||||||
|
bool Read(EStandardHandle stream, const AuMemoryViewStreamWrite &destination, bool nonblock) override;
|
||||||
|
bool Write(const AuMemoryViewStreamRead &source) override;
|
||||||
|
|
||||||
|
bool Start() override;
|
||||||
|
|
||||||
|
bool Init();
|
||||||
|
|
||||||
|
void ByeLol(AuSInt code);
|
||||||
|
private:
|
||||||
|
|
||||||
|
int pipeStdOut_[2]{};
|
||||||
|
int pipeStdErr_[2]{};
|
||||||
|
int pipeStdIn_ [2]{};
|
||||||
|
|
||||||
|
AuThreadPrimitives::EventShared_t finished_;
|
||||||
|
|
||||||
|
StartupParmaters startup_;
|
||||||
|
ESpawnType type_;
|
||||||
|
|
||||||
|
AuList<const char *> cargs_;
|
||||||
|
AuString debug_;
|
||||||
|
|
||||||
|
pid_t pidt_;
|
||||||
|
bool alive_ {};
|
||||||
|
|
||||||
|
AuSInt exitCode_;
|
||||||
|
};
|
||||||
|
|
||||||
|
ProcessImpl::ProcessImpl(const StartupParmaters ¶ms) : startup_(params)
|
||||||
|
{
|
||||||
|
AuIOFS::NormalizePath(this->startup_.process, this->startup_.process);
|
||||||
|
|
||||||
|
this->startup_.args.insert(startup_.args.begin(), startup_.process);
|
||||||
|
|
||||||
|
for (const auto &arg : this->startup_.args)
|
||||||
|
{
|
||||||
|
this->cargs_.push_back(arg.c_str());
|
||||||
|
this->debug_ += arg + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cargs_.push_back(nullptr);
|
||||||
|
if (this->debug_.size())
|
||||||
|
{
|
||||||
|
this->debug_.resize(this->debug_.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessImpl::~ProcessImpl()
|
||||||
|
{
|
||||||
|
if (this->type_ == ESpawnType::eSpawnChildProcessWorker)
|
||||||
|
{
|
||||||
|
TryKill();
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gSpinLock);
|
||||||
|
AuTryRemove(gPidLookupMap, this->pidt_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->alive_)
|
||||||
|
{
|
||||||
|
if (this->type_ == ESpawnType::eSpawnThreadLeader)
|
||||||
|
{
|
||||||
|
::kill(this->pidt_, SIGCONT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShutdownPipes();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt ProcessImpl::GetProcessId()
|
||||||
|
{
|
||||||
|
return this->pidt_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessImpl::ByeLol(AuSInt code)
|
||||||
|
{
|
||||||
|
this->exitCode_ = code;
|
||||||
|
|
||||||
|
if (this->finished_)
|
||||||
|
{
|
||||||
|
this->finished_->Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessImpl::ShutdownPipes()
|
||||||
|
{
|
||||||
|
if (auto fd = AuExchange(pipeStdErr_[0], {})) close(fd);
|
||||||
|
if (auto fd = AuExchange(pipeStdErr_[1], {})) close(fd);
|
||||||
|
if (auto fd = AuExchange(pipeStdOut_[0], {})) close(fd);
|
||||||
|
if (auto fd = AuExchange(pipeStdOut_[1], {})) close(fd);
|
||||||
|
if (auto fd = AuExchange(pipeStdIn_[0], {})) close(fd);
|
||||||
|
if (auto fd = AuExchange(pipeStdIn_[1], {})) close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::TryKill()
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gSpinLock);
|
||||||
|
if (this->alive_)
|
||||||
|
{
|
||||||
|
return ::kill(this->pidt_, SIGTERM) == 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::Terminate()
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gSpinLock);
|
||||||
|
if (this->alive_)
|
||||||
|
{
|
||||||
|
return ::kill(this->pidt_, SIGKILL) == 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSPtr<Aurora::Threading::IWaitable> ProcessImpl::AsWaitable()
|
||||||
|
{
|
||||||
|
return this->finished_;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuSInt ProcessImpl::GetExitCode()
|
||||||
|
{
|
||||||
|
return this->exitCode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::Read(EStandardHandle stream, const AuMemoryViewStreamWrite &destination, bool nonblock)
|
||||||
|
{
|
||||||
|
auto handle = stream == EStandardHandle::eStdError ? this->pipeStdErr_[0] : this->pipeStdOut_[0];
|
||||||
|
if (handle < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto control = fcntl(handle, F_GETFL);
|
||||||
|
auto ref = control;
|
||||||
|
|
||||||
|
if (nonblock)
|
||||||
|
{
|
||||||
|
control |= O_NONBLOCK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
control &= ~O_NONBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref != control)
|
||||||
|
{
|
||||||
|
fcntl(handle, F_SETFL, control);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tmp = read(handle, destination.ptr, destination.length);
|
||||||
|
if (tmp < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.outVariable = tmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::Write(const AuMemoryViewStreamRead &source)
|
||||||
|
{
|
||||||
|
auto handle = pipeStdIn_[1];
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return write(handle, source.ptr, source.length) == source.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::Init()
|
||||||
|
{
|
||||||
|
if (this->startup_.fwdOut)
|
||||||
|
{
|
||||||
|
if (!pipe(this->pipeStdOut_))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->startup_.fwdErr)
|
||||||
|
{
|
||||||
|
if (!pipe(this->pipeStdErr_))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->startup_.fwdIn)
|
||||||
|
{
|
||||||
|
if (!pipe(this->pipeStdIn_))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->finished_ = AuThreadPrimitives::EventShared(false, false, true);
|
||||||
|
return bool(this->finished_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessImpl::Start()
|
||||||
|
{
|
||||||
|
this->exitCode_ = 0x10110100;
|
||||||
|
|
||||||
|
if (this->type_ == ESpawnType::eSpawnOvermap)
|
||||||
|
{
|
||||||
|
execv(this->startup_.process.c_str(), (char *const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
||||||
|
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->startup_.process, this->debug_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
{
|
||||||
|
//Threading::Primitives::Semaphore semaphore;
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this->startup_.fwdIn)
|
||||||
|
{
|
||||||
|
dup2(pipeStdIn_[0], STDIN_FILENO);
|
||||||
|
close(AuExchange(pipeStdIn_[0], 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->startup_.fwdErr)
|
||||||
|
{
|
||||||
|
dup2(pipeStdErr_[1], STDERR_FILENO);
|
||||||
|
close(AuExchange(pipeStdErr_[1], 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->startup_.fwdOut)
|
||||||
|
{
|
||||||
|
dup2(pipeStdOut_[1], STDOUT_FILENO);
|
||||||
|
close(AuExchange(pipeStdOut_[1], 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->type_ != ESpawnType::eSpawnChildProcessWorker)
|
||||||
|
{
|
||||||
|
setsid();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gSpinLock);
|
||||||
|
AuTryInsert(gPidLookupMap, getpid(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->alive_ = true;
|
||||||
|
|
||||||
|
//semaphore.Unlock();
|
||||||
|
|
||||||
|
execv(this->startup_.process.c_str(), (char * const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
|
||||||
|
|
||||||
|
SysPushErrorGen("execv didn't overwrite the process map, given {} ({})", this->startup_.process, this->debug_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (pid < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->pidt_ = pid;
|
||||||
|
|
||||||
|
//semaphore.Lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM IProcess *SpawnNew(const StartupParmaters ¶ms)
|
||||||
|
{
|
||||||
|
auto ret = _new ProcessImpl(params);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret->Init())
|
||||||
|
{
|
||||||
|
delete ret;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM void SpawnRelease(IProcess *process)
|
||||||
|
{
|
||||||
|
AuSafeDelete<ProcessImpl *>(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleChildTermiantion(pid_t pid, int code)
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(gSpinLock);
|
||||||
|
|
||||||
|
auto handler = gPidLookupMap.find(pid);
|
||||||
|
if (handler == gPidLookupMap.end()) return;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto process = *handler;
|
||||||
|
process.second->ByeLol(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
gPidLookupMap.erase(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SigChldHandler(int)
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
pid = wait3(&code, WNOHANG, nullptr);
|
||||||
|
|
||||||
|
if ((pid == 0) ||
|
||||||
|
(pid == -1))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleChildTermiantion(pid, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitUnix()
|
||||||
|
{
|
||||||
|
signal(SIGCHLD, SigChldHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeinitUnix()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,14 @@
|
|||||||
/***
|
/***
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: Process.Unix.hpp
|
||||||
File: Process.Linux.hpp
|
File: Process.Linux.hpp
|
||||||
Date: 2021-6-12
|
Date: 2021-6-12
|
||||||
Author: Reece
|
Author: Reece
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
void DeinitUnix();
|
||||||
|
void InitUnix();
|
||||||
|
}
|
@ -13,6 +13,10 @@
|
|||||||
#include "Open.Win32.hpp"
|
#include "Open.Win32.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
#include "Process.Unix.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Aurora::Processes
|
namespace Aurora::Processes
|
||||||
{
|
{
|
||||||
void Init()
|
void Init()
|
||||||
@ -21,6 +25,10 @@ namespace Aurora::Processes
|
|||||||
InitWin32();
|
InitWin32();
|
||||||
InitWin32Opener();
|
InitWin32Opener();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
InitUnix();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deinit()
|
void Deinit()
|
||||||
@ -29,5 +37,9 @@ namespace Aurora::Processes
|
|||||||
DeinitWin32();
|
DeinitWin32();
|
||||||
DeinitWin32Opener();
|
DeinitWin32Opener();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
DeinitUnix();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ namespace Aurora::Threading::Threads
|
|||||||
return {false, 0};
|
return {false, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto callVoidPtr_f = [](void *that) -> void
|
static auto OSEP_f = [](void *that) -> void *
|
||||||
{
|
{
|
||||||
auto handle = reinterpret_cast<AuFunction<void()> *>(that);
|
auto handle = reinterpret_cast<AuFunction<void()> *>(that);
|
||||||
auto callMe = *handle;
|
auto callMe = *handle;
|
||||||
@ -40,13 +40,6 @@ namespace Aurora::Threading::Threads
|
|||||||
callMe();
|
callMe();
|
||||||
};
|
};
|
||||||
|
|
||||||
void *(*OSEP_f)(void *) = [](void *that) -> void *
|
|
||||||
{
|
|
||||||
auto thiz = reinterpret_cast<OSThread *>(that);
|
|
||||||
thiz->_ThreadEP();
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto ret = pthread_attr_init(&tattr);
|
auto ret = pthread_attr_init(&tattr);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user