AuroraRuntime/Source/IO/IPC/IPCHandle.cpp

317 lines
9.4 KiB
C++
Raw Normal View History

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IPCHandle.cpp
Date: 2022-4-13
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "IPC.hpp"
#include "IPCHandle.hpp"
namespace Aurora::IO::IPC
{
#define AURORA_IPC_BRAND "AuroraIPC_"
2022-07-21 06:18:53 +00:00
IPCToken::IPCToken()
{
AuMemset(this, 0, sizeof(*this));
}
2022-07-21 06:18:53 +00:00
AuString IPCToken::ToNTPath() const
{
if (this->pid)
{
return "Global\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16);
}
else
{
return "Local\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16);
}
}
2022-07-21 06:18:53 +00:00
AuUInt32 IPCToken::ToUnixServerCookie() const
{
2022-07-21 06:18:53 +00:00
return this->cookie;
}
2022-07-21 06:18:53 +00:00
void IPCToken::NewId()
{
2022-07-21 06:18:53 +00:00
#if defined(AURORA_IS_POSIX_DERIVED)
while (!this->cookie)
{
this->cookie = AuRng::RngU32();
}
2022-07-21 06:18:53 +00:00
#else
auto temp = AuRng::ReadString(AuArraySize(this->path), AuRng::ERngStringCharacters::eAlphaNumericCharacters);
2022-04-15 18:20:12 +00:00
AuMemcpy(this->path, temp.data(), temp.size());
2022-07-21 06:18:53 +00:00
#endif
}
2022-07-21 06:18:53 +00:00
IPCHandle::IPCHandle()
{
#if defined(AURORA_IS_POSIX_DERIVED)
this->pid = getpid();
#endif
}
bool IPCHandle::IsTopEq(EIPCHandleType type) const
{
2022-07-21 06:18:53 +00:00
if (this->values.empty())
{
return false;
}
2022-07-21 06:18:53 +00:00
return this->values[0].subtype == type;
}
Further Linux support [+] Begin work on IO futexes for io release on process/thread exit [+] Linux ::readdir iteration [+] AuConsole buffering API [*] Fix sleep as to not get interrupted by signals [*] Switch the type of FS lock used under Linux [*] Linux: Use new IPCHandle encoding scheme [*] Fix undefined behaviour: unintialized timeout values (AuLoop/Linux) [*] Fix undefined behaviour: ConsoleTTY clear line was called of a color of a random value on stack [-] Remainings of std dir iterator [*] Fix pthread_kill (aka send signal to pthread handle) always kills process. This is what you expect bc signal handler inheritance. [*] Reformat the build Aurora.json file [+] Added clang warning ignores to the build file [*] Fix: UNIX need to use STDOUT_FILENO. Was using CRT handle in place of fd by mistake. [+] Linux implementation for IO yield (AuIO::IOYield() - UNIX::LinuxOverlappedYield()) [*] Fix: Linux async end of stream processing. res 0 = zero bytes consumed. <= was detecting this as an error of code 0. Should succeed with zero bytes. [+] Linux LoopQueue missing epilogue hook for the IO processor [*] Various refactors and minor bug fixes [*] Linux fix: Handle pipe EOS as zero [*] Linux fix: thread termination via a user signal of 77. Need a force terminate. [*] IPC handle: fix improper int to bool cast in the header setup within ToString [*] Linux fix: HWInfo CPU topology regression [-] Linux fix: remove SIGABRT handler [*] Missing override in compression, exit, and consoletty headers. [+] Unix Syslog logger backend
2022-08-02 04:52:17 +00:00
bool IPCHandle::PushId(EIPCHandleType type, const IPCToken &token)
2022-07-21 06:18:53 +00:00
{
IPCValue val;
val.subtype = type;
val.token = token;
return AuTryInsert(this->values, val) && this->values.size() < 7;
}
2022-07-21 06:18:53 +00:00
IPCValue *IPCHandle::GetToken(EIPCHandleType type, int id)
{
if (this->values.size() <= id)
{
2022-07-21 06:18:53 +00:00
return {};
}
2022-07-21 06:18:53 +00:00
auto val = &this->values[id];
if (val->subtype != type)
2022-04-15 18:20:12 +00:00
{
2022-07-21 06:18:53 +00:00
return {};
2022-04-15 18:20:12 +00:00
}
2022-07-21 06:18:53 +00:00
return val;
}
2022-07-21 06:18:53 +00:00
bool IPCHandle::FromString(const AuString &in)
{
AuString nextToken;
AuUInt nextInt;
2022-07-21 06:18:53 +00:00
if (in.size() < 2)
{
return false;
}
2022-07-21 06:25:45 +00:00
AuUInt32 magic {0x811c9dc5};
for (int i = 0; i < in.size() - 2; i++)
{
2022-07-21 06:25:45 +00:00
magic ^= (in[i] * 0x01000193);
}
if (AuUInt8(AuUInt8(in[in.size() - 2] - 'A') & 15) != AuUInt8(magic & 15))
{
return false;
}
if (AuUInt8(AuUInt8(in[in.size() - 1] - 'A') & 15) != AuUInt8((magic >> 4) & 15))
{
return false;
}
#define READ_NEXT_TOKEN \
{ \
nextToken.clear(); \
\
if (((in.size() - stringOffset) < 2)) \
{ \
return false; \
} \
\
char cur; \
while (((stringOffset) < in.size()) && \
((cur = in[stringOffset]) != ':')) \
{ \
nextToken.push_back(cur); \
stringOffset++; \
} \
stringOffset++; \
2022-07-21 06:18:53 +00:00
}
2022-07-21 06:18:53 +00:00
#define READ_NEXT_INT \
{ \
char cur; \
auto startOffset = stringOffset; \
while (((stringOffset) < in.size()) && \
((cur = in[stringOffset]) != ':')) \
2022-07-21 06:18:53 +00:00
{ \
stringOffset++; \
} \
const char *endPtr = &in[stringOffset]; \
2022-07-21 06:18:53 +00:00
const char *startPtr = &in[startOffset]; \
stringOffset++; \
auto nextIntOpt = AuParse::ParseUInt16(startPtr, endPtr); \
2022-07-21 06:18:53 +00:00
if (!nextIntOpt.has_value()) \
{ \
return false; \
} \
nextInt = nextIntOpt.value(); \
}
2022-07-21 06:18:53 +00:00
int stringOffset {};
int count {};
while (in.size() > (stringOffset + 2))
{
2022-07-21 06:18:53 +00:00
int index = count++;
IPCHeader header;
2022-07-21 06:18:53 +00:00
header.bValue = AuUInt8((((in[stringOffset + 1] - 'A') & 15) << 4) |
2022-07-21 06:34:55 +00:00
((in[stringOffset + 0] - 'A') & 15));
2022-07-21 06:18:53 +00:00
stringOffset += 2;
if (index == 0 && header.bmHasPid)
{
READ_NEXT_INT;
this->pid = nextInt;
}
2022-07-21 06:25:45 +00:00
auto readIPC = [&](IPCHeader header, IPCValue &value)
2022-07-21 06:18:53 +00:00
{
value.subtype = (EIPCHandleType)header.bmType;
if (header.bmHasWord)
{
READ_NEXT_INT;
value.token.word = nextInt;
}
else
{
value.token.word = 0;
}
if constexpr (AuBuild::kIsNtDerived)
{
READ_NEXT_TOKEN;
value.token.cookie = nextInt;
if (nextToken.size() > 16)
{
return false;
}
AuMemcpy(value.token.path, nextToken.data(), AuMin<AuUInt8>(nextToken.size() + 1, AuArraySize(value.token.path)));
}
else
{
READ_NEXT_INT;
value.token.cookie = nextInt;
}
return true;
};
if (header.bmArray)
{
for (int i = 0; i < header.bmArray; i++)
{
IPCHeader header2;
if (i == 0)
{
header2 = header;
}
else
{
header2.bValue = (in[stringOffset] - 'A') & 15;
stringOffset++;
}
IPCValue value;
value.token.pid = this->pid;
2022-07-21 06:34:55 +00:00
if (!readIPC(header2, value))
{
return false;
}
2022-07-21 06:18:53 +00:00
this->values.push_back(value);
}
}
else
{
IPCValue value;
value.token.pid = this->pid;
2022-07-21 06:34:55 +00:00
if (!readIPC(header, value))
{
return false;
}
2022-07-21 06:18:53 +00:00
this->values.push_back(value);
}
}
return true;
}
AuString IPCHandle::ToString() const
{
AuString ret;
2022-07-21 06:18:53 +00:00
int count {};
for (const auto &ipcValue : this->values)
{
2022-07-21 06:18:53 +00:00
int index = count++;
IPCHeader header;
2022-07-21 06:18:53 +00:00
header.bmArray = index == 0 ? this->values.size() : 0;
Further Linux support [+] Begin work on IO futexes for io release on process/thread exit [+] Linux ::readdir iteration [+] AuConsole buffering API [*] Fix sleep as to not get interrupted by signals [*] Switch the type of FS lock used under Linux [*] Linux: Use new IPCHandle encoding scheme [*] Fix undefined behaviour: unintialized timeout values (AuLoop/Linux) [*] Fix undefined behaviour: ConsoleTTY clear line was called of a color of a random value on stack [-] Remainings of std dir iterator [*] Fix pthread_kill (aka send signal to pthread handle) always kills process. This is what you expect bc signal handler inheritance. [*] Reformat the build Aurora.json file [+] Added clang warning ignores to the build file [*] Fix: UNIX need to use STDOUT_FILENO. Was using CRT handle in place of fd by mistake. [+] Linux implementation for IO yield (AuIO::IOYield() - UNIX::LinuxOverlappedYield()) [*] Fix: Linux async end of stream processing. res 0 = zero bytes consumed. <= was detecting this as an error of code 0. Should succeed with zero bytes. [+] Linux LoopQueue missing epilogue hook for the IO processor [*] Various refactors and minor bug fixes [*] Linux fix: Handle pipe EOS as zero [*] Linux fix: thread termination via a user signal of 77. Need a force terminate. [*] IPC handle: fix improper int to bool cast in the header setup within ToString [*] Linux fix: HWInfo CPU topology regression [-] Linux fix: remove SIGABRT handler [*] Missing override in compression, exit, and consoletty headers. [+] Unix Syslog logger backend
2022-08-02 04:52:17 +00:00
header.bmHasPid = index == 0 ? (this->pid ? 1 : 0) : 0;
2022-07-21 06:18:53 +00:00
header.bmType = (AuUInt8)ipcValue.subtype;
header.bmHasWord = (AuUInt8)(ipcValue.token.word ? 1 : 0);
2022-07-21 06:18:53 +00:00
ret += ('A' + ((header.bValue & 15)));
2022-07-21 06:18:53 +00:00
if (!index)
{
ret += ('A' + ((header.bValue >> 4) & 15));
}
2022-07-21 06:18:53 +00:00
if (header.bmHasPid)
{
ret += AuParse::StringifyUInt16(this->pid, false);
2022-07-21 06:18:53 +00:00
ret += ':';
}
2022-07-21 06:18:53 +00:00
if (header.bmHasWord)
{
ret += AuParse::StringifyUInt16(ipcValue.token.word, false);
2022-07-21 06:18:53 +00:00
ret += ':';
}
if constexpr (AuBuild::kIsNtDerived)
{
ret += AuString(ipcValue.token.path, ipcValue.token.path + strnlen(ipcValue.token.path, AuArraySize(ipcValue.token.path)));
ret += ':';
}
else
{
ret += AuParse::StringifyUInt16(ipcValue.token.cookie, false);
2022-07-21 06:18:53 +00:00
ret += ':';
}
}
2022-07-21 06:18:53 +00:00
AuUInt32 magic {0x811c9dc5};
2022-07-21 06:18:53 +00:00
for (int i = 0; i < ret.size(); i++)
{
2022-07-21 06:25:45 +00:00
magic ^= (ret[i] * 0x01000193);
}
2022-07-21 06:18:53 +00:00
ret.push_back(((magic & 15) + 'A'));
ret.push_back((((magic >> 4) & 15) + 'A'));
2022-07-21 06:18:53 +00:00
return ret;
}
#if defined(AURORA_IS_POSIX_DERIVED)
pid_t IPCHandle::ToUnixPid() const
{
return this->pid;
}
Further Linux support [+] Begin work on IO futexes for io release on process/thread exit [+] Linux ::readdir iteration [+] AuConsole buffering API [*] Fix sleep as to not get interrupted by signals [*] Switch the type of FS lock used under Linux [*] Linux: Use new IPCHandle encoding scheme [*] Fix undefined behaviour: unintialized timeout values (AuLoop/Linux) [*] Fix undefined behaviour: ConsoleTTY clear line was called of a color of a random value on stack [-] Remainings of std dir iterator [*] Fix pthread_kill (aka send signal to pthread handle) always kills process. This is what you expect bc signal handler inheritance. [*] Reformat the build Aurora.json file [+] Added clang warning ignores to the build file [*] Fix: UNIX need to use STDOUT_FILENO. Was using CRT handle in place of fd by mistake. [+] Linux implementation for IO yield (AuIO::IOYield() - UNIX::LinuxOverlappedYield()) [*] Fix: Linux async end of stream processing. res 0 = zero bytes consumed. <= was detecting this as an error of code 0. Should succeed with zero bytes. [+] Linux LoopQueue missing epilogue hook for the IO processor [*] Various refactors and minor bug fixes [*] Linux fix: Handle pipe EOS as zero [*] Linux fix: thread termination via a user signal of 77. Need a force terminate. [*] IPC handle: fix improper int to bool cast in the header setup within ToString [*] Linux fix: HWInfo CPU topology regression [-] Linux fix: remove SIGABRT handler [*] Missing override in compression, exit, and consoletty headers. [+] Unix Syslog logger backend
2022-08-02 04:52:17 +00:00
pid_t IPCToken::ToUnixPid() const
{
return this->pid;
}
#endif
}