[+] AuProcess::EnvironmentGetAll
[+] AuProcess::EnvironmentGetOne [+] AuProcess::EnvironmentSetOne [+] AuProcess::EnvironmentRemoveOne [+] AuProcess::EnvironmentRemoveMany [+] AuProcess::EnvironmentSetMany [+] AuProcess::GetProcessStartupTimeNS [+] AuProcess::GetProcessStartupTimeMS [*] Note WakeOnAddress on all platforms [*] Updated READMEs
This commit is contained in:
parent
a977f0d1b5
commit
bdec6ff8ba
@ -11,6 +11,8 @@
|
||||
#include "ProcessMap.hpp"
|
||||
#include "IProcessSectionMapView.hpp"
|
||||
#include "IProcessSectionView.hpp"
|
||||
#include "ProcessEnvironment.hpp"
|
||||
#include "ProcessStartTime.hpp"
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
|
38
Include/Aurora/Process/ProcessEnvironment.hpp
Normal file
38
Include/Aurora/Process/ProcessEnvironment.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ProcessEnvironment.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
|
||||
Note: I can't stand environment variables.
|
||||
They're leftover POSIX shitstains used for configuration during process initialization of yesteryear (muh 'stdio/out ipc all the tiny things to build big things' model of computer operating systems).
|
||||
The underlying environ block as described by the POSIX specifications is inherently thread unsafe, and hasn't carried itself into the modern era of computing past its' usage for shell $%PATH$% expansion...
|
||||
Well, maybe there's software in the UNIX ecosystem glued together with XDG_HOPES_AND_DREAMS. I try not to think about those.
|
||||
Well, maybe I'm forgetting the primary user of env-vars... JAVA_HOME!!! I suppose we can't forget about those few Java programs that don't ship the JRE & have startup.[sh/bat] scripts.
|
||||
|
||||
Alternatives:
|
||||
* Win32 users are better served by the Windows registry
|
||||
* Linux drivers have module_param to avoid early file io
|
||||
* NT drivers can query the registry via RtlXXXXX APIs
|
||||
* Userland IPC identification between child processes can be served by AuCmdLine
|
||||
* Unix services are a mess of non-standard configuration files
|
||||
Depending on the use case and OS, early application configuration on modern Unix (^) will differ
|
||||
^: IE: A MacOS application package, a Linux server program with nonstandard configs+yamls, or BSD systems with xml interfaces will all want different IO
|
||||
* Sqlite for large application configuration stores
|
||||
|
||||
Warning:
|
||||
Aurora Runtime, in a bid to support environment variables properly in userland (ie: not emulating the api with no real effects in real-time), does not buffer the block
|
||||
Other code in a UNIX process can bypass the mutex required for that respective platform
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
AUKN_SYM AuList<AuPair<AuString, AuString>> EnvironmentGetAll();
|
||||
AUKN_SYM AuOptional<AuString> EnvironmentGetOne(const AuString &key);
|
||||
AUKN_SYM bool EnvironmentSetOne(const AuString &key, const AuString &value);
|
||||
AUKN_SYM bool EnvironmentRemoveOne(const AuString &key);
|
||||
AUKN_SYM bool EnvironmentRemoveMany(const AuList<AuString> &list);
|
||||
AUKN_SYM bool EnvironmentSetMany(const AuList<AuPair<AuString, AuString>> &list);
|
||||
}
|
21
Include/Aurora/Process/ProcessStartTime.hpp
Normal file
21
Include/Aurora/Process/ProcessStartTime.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ProcessStartTime.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
/**
|
||||
* @brief Defer to the AuTime namespace to convert the return unsigned integer to something useful
|
||||
*/
|
||||
AUKN_SYM AuUInt64 GetProcessStartupTimeNS();
|
||||
|
||||
/**
|
||||
* @brief Defer to the AuTime namespace to convert the return unsigned integer to something useful
|
||||
*/
|
||||
AUKN_SYM AuUInt64 GetProcessStartupTimeMS();
|
||||
}
|
@ -3,8 +3,10 @@
|
||||
|
||||
# Features
|
||||
* Thread synchronization primitives: condition ex, condition mutex, condition variable, critical section, event, mutex, rwlock, semaphore, and spinlock
|
||||
* All primitives include a trylock and a timed lock member
|
||||
* All primitives include a trylock and a nanosecond-resolution timed lock methods
|
||||
* SleepNs function supporting higher resolution sleep available than in most APIs (^1)
|
||||
* Enchanced Win32 support with increased yield resolution and optimization around internal XP, internal Win8, and UWP APIs
|
||||
* WakeOnAddress support on every operating system regardless of kernel support
|
||||
* Thread Object per native OS thread
|
||||
* Thread spawning with TLS handles and shutdown routines dispatched under pseudo fibers
|
||||
* Update thread affinity, throttle, name, and related attributes
|
||||
|
@ -18,12 +18,13 @@ pipeline to get started.
|
||||
- Crypto ECC/[25519, P-384, P-256], [AES, RSA, X509], CBC[AES, Stinky3DES], HMAC, HashCash, BCrypt, [common digests]
|
||||
- Basic cmdline parsing from any module
|
||||
- Exit and fatal save condition callbacks
|
||||
- Random; secure, user-seeded, and fast
|
||||
- Random; secure and fast user-seeded backends
|
||||
- Hardware Info; memory and cpu info (including cpu feature bits, core topology, e-core awareness, and basic cache size)
|
||||
- Software stack information for retrieving kernel, version, brand, family, build string, etc
|
||||
- Compression (deflate, gzip, zstd, LZ4, bzip2, TODO: lzma, brotli)
|
||||
- Compression (deflate, gzip, zstd, LZ4, bzip2, lzma, brotli)
|
||||
- Locale and encoding
|
||||
- High performance threading and synchronization primitives (os userland sched optimized)
|
||||
- Alternative WakeOnAddress implementation for non-aurt/user synchronization primitives when kernel support is missing (polyfill when faced with old and/or locked down private APIs)
|
||||
- Async subsystem backed by high performance sync primitives (cv loop) and hybrid switching into IO polling (think userland cv-backed promises + waitmultipleobjects)
|
||||
- IO subsystem for standard cross-platform IO loop queues, IPC (mutex with auto-unlock, semaphores, full-duplex single-connection pipes, and shared memory), file (direct uncached access), and network
|
||||
- Abstract kernel IO transactions, IPC objects, timers, semaphores, and others in the form of ILoopSources
|
||||
|
132
Source/Process/AuProcessEnvironment.NT.cpp
Normal file
132
Source/Process/AuProcessEnvironment.NT.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.NT.cpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "AuProcessEnvironment.hpp"
|
||||
#include "AuProcessEnvironment.NT.hpp"
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
AUKN_SYM AuList<AuPair<AuString, AuString>> EnvironmentGetAll()
|
||||
{
|
||||
AuList<AuPair<AuString, AuString>> ret;
|
||||
|
||||
auto pWideStrings = ::GetEnvironmentStringsW();
|
||||
auto pFreeBase = pWideStrings;
|
||||
|
||||
while (auto uLength = ::wcslen(pWideStrings))
|
||||
{
|
||||
auto utfString = AuLocale::ConvertFromWChar(pWideStrings, uLength);
|
||||
|
||||
if (utfString.empty())
|
||||
{
|
||||
::FreeEnvironmentStringsW(pFreeBase);
|
||||
SysPushErrorNested();
|
||||
return {};
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto optSplit = EnvironmentSplitString(utfString);
|
||||
if (optSplit)
|
||||
{
|
||||
ret.push_back(optSplit.value());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
::FreeEnvironmentStringsW(pFreeBase);
|
||||
SysPushErrorCatch();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
pWideStrings += uLength;
|
||||
pWideStrings += 1;
|
||||
}
|
||||
|
||||
::FreeEnvironmentStringsW(pFreeBase);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AUKN_SYM AuOptional<AuString> EnvironmentGetOne(const AuString &key)
|
||||
{
|
||||
auto keyString = AuLocale::ConvertFromUTF8(key);
|
||||
|
||||
if (keyString.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto uLength = ::GetEnvironmentVariableW(keyString.c_str(),
|
||||
nullptr,
|
||||
0);
|
||||
|
||||
if (uLength == 0)
|
||||
{
|
||||
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
{
|
||||
SysPushErrorResourceMissing();
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring temp;
|
||||
|
||||
if (!AuTryResize(temp, uLength))
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return {};
|
||||
}
|
||||
|
||||
uLength = ::GetEnvironmentVariableW(keyString.c_str(),
|
||||
temp.data(),
|
||||
temp.size());
|
||||
|
||||
if (!uLength)
|
||||
{
|
||||
SysPushErrorGeneric();
|
||||
return {};
|
||||
}
|
||||
|
||||
temp.resize(uLength);
|
||||
return AuLocale::ConvertFromWChar(temp.c_str());
|
||||
}
|
||||
|
||||
AUKN_SYM bool EnvironmentSetOne(const AuString &key, const AuString &value)
|
||||
{
|
||||
auto keyString = AuLocale::ConvertFromUTF8(key);
|
||||
auto valString = AuLocale::ConvertFromUTF8(value);
|
||||
|
||||
if (keyString.empty() || valString.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::SetEnvironmentVariableW(keyString.c_str(),
|
||||
valString.c_str());
|
||||
}
|
||||
|
||||
AUKN_SYM bool EnvironmentRemoveOne(const AuString &key)
|
||||
{
|
||||
std::wstring keyString;
|
||||
|
||||
if ((keyString = AuLocale::ConvertFromUTF8(key)).size())
|
||||
{
|
||||
return ::SetEnvironmentVariableW(keyString.c_str(), nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
13
Source/Process/AuProcessEnvironment.NT.hpp
Normal file
13
Source/Process/AuProcessEnvironment.NT.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.NT.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
|
||||
}
|
71
Source/Process/AuProcessEnvironment.Unix.cpp
Normal file
71
Source/Process/AuProcessEnvironment.Unix.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.Unix.cpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "AuProcessEnvironment.hpp"
|
||||
#include "AuProcessEnvironment.Unix.hpp"
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
static AuThreadPrimitives::Mutex gEnvMutex;
|
||||
|
||||
AUKN_SYM AuList<AuPair<AuString, AuString>> EnvironmentGetAll()
|
||||
{
|
||||
AU_LOCK_GUARD(gEnvMutex);
|
||||
AuList<AuPair<AuString, AuString>> ret;
|
||||
|
||||
auto pIterator = environ;
|
||||
while (auto pCurrent = *(pIterator++))
|
||||
{
|
||||
auto optSplit = EnvironmentSplitString(pCurrent);
|
||||
if (optSplit)
|
||||
{
|
||||
ret.push_back(optSplit.value());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AUKN_SYM AuOptional<AuString> EnvironmentGetOne(const AuString &key)
|
||||
{
|
||||
AU_LOCK_GUARD(gEnvMutex);
|
||||
|
||||
if (key.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pValue = ::getenv(key.c_str());
|
||||
return pValue ? AuString(pValue) : AuOptional<AuString> {};
|
||||
}
|
||||
|
||||
AUKN_SYM bool EnvironmentSetOne(const AuString &key, const AuString &value)
|
||||
{
|
||||
AU_LOCK_GUARD(gEnvMutex);
|
||||
|
||||
if (key.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::setenv(key.c_str(), value.c_str(), 1) == 0;
|
||||
}
|
||||
|
||||
AUKN_SYM bool EnvironmentRemoveOne(const AuString &key)
|
||||
{
|
||||
AU_LOCK_GUARD(gEnvMutex);
|
||||
|
||||
if (key.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::unsetenv(key.c_str()) == 0;
|
||||
}
|
||||
}
|
13
Source/Process/AuProcessEnvironment.Unix.hpp
Normal file
13
Source/Process/AuProcessEnvironment.Unix.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.Unix.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
|
||||
}
|
63
Source/Process/AuProcessEnvironment.cpp
Normal file
63
Source/Process/AuProcessEnvironment.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.cpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "AuProcessEnvironment.hpp"
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
AUKN_SYM bool EnvironmentRemoveMany(const AuList<AuString> &list)
|
||||
{
|
||||
bool bFailed {};
|
||||
|
||||
for (const auto &key : list)
|
||||
{
|
||||
if (!EnvironmentRemoveOne(key))
|
||||
{
|
||||
bFailed |= true;
|
||||
}
|
||||
}
|
||||
|
||||
return !bFailed;
|
||||
}
|
||||
|
||||
|
||||
AUKN_SYM bool EnvironmentSetMany(const AuList<AuPair<AuString, AuString>> &list)
|
||||
{
|
||||
for (const auto &[key, value] : list)
|
||||
{
|
||||
if (!EnvironmentSetOne(key, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AuOptional<AuPair<AuString, AuString>> EnvironmentSplitString(const AuString &str)
|
||||
{
|
||||
auto uIdx = str.find('=');
|
||||
|
||||
if (uIdx == str.npos)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (uIdx == 0)
|
||||
{
|
||||
// Ignore Microsoft DOS shell environment hints
|
||||
// Expect to see:
|
||||
// <empty>=::=::\
|
||||
// (opt) <empty>=<drive letter>:=<user home>
|
||||
// (opt) <empty>=ExitCode={:08x}
|
||||
return {};
|
||||
}
|
||||
|
||||
return AuMakePair(str.substr(0, uIdx), str.substr(uIdx + 1));
|
||||
}
|
||||
}
|
13
Source/Process/AuProcessEnvironment.hpp
Normal file
13
Source/Process/AuProcessEnvironment.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessEnvironment.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
AuOptional<AuPair<AuString, AuString>> EnvironmentSplitString(const AuString &str);
|
||||
}
|
40
Source/Process/AuProcessStartTime.cpp
Normal file
40
Source/Process/AuProcessStartTime.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessStartTime.cpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "AuProcessStartTime.hpp"
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
AUKN_SYM AuUInt64 GetProcessStartupTimeNS()
|
||||
{
|
||||
static AuOptional<AuUInt64> optKnownWallTime;
|
||||
|
||||
if (optKnownWallTime.has_value())
|
||||
{
|
||||
return optKnownWallTime.value();
|
||||
}
|
||||
|
||||
auto uUptime = AuTime::ProcessClockNS();
|
||||
|
||||
if (!uUptime)
|
||||
{
|
||||
optKnownWallTime = AuTime::CurrentClockNS();
|
||||
}
|
||||
else
|
||||
{
|
||||
optKnownWallTime = AuTime::CurrentClockNS() - uUptime;
|
||||
}
|
||||
|
||||
return optKnownWallTime.value();
|
||||
}
|
||||
|
||||
AUKN_SYM AuUInt64 GetProcessStartupTimeMS()
|
||||
{
|
||||
return AuNSToMS<AuUInt64>(GetProcessStartupTimeNS());
|
||||
}
|
||||
}
|
13
Source/Process/AuProcessStartTime.hpp
Normal file
13
Source/Process/AuProcessStartTime.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuProcessStartTime.hpp
|
||||
Date: 2023-7-10
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user