This commit is contained in:
2025-11-26 18:56:23 +05:30
parent dd5e60445b
commit d9756df436
4 changed files with 134 additions and 4 deletions

View File

@ -250,7 +250,7 @@ namespace IACore
size_ = static_cast<size_t>(size.QuadPart); size_ = static_cast<size_t>(size.QuadPart);
// 3. Create Mapping Object // 3. Create Mapping Object
hMapping_ = ::CreateFileMappingA(hFile_, nullptr, PAGE_READONLY, 0, 0, nullptr); hMapping_ = ::CreateFileMappingA(hFile_, nullptr, PAGE_READWRITE, 0, 0, nullptr);
if (!hMapping_) if (!hMapping_)
{ {
Close(); Close();
@ -258,7 +258,7 @@ namespace IACore
} }
// 4. Map View // 4. Map View
data_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); data_ = ::MapViewOfFile(hMapping_, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (!data_) if (!data_)
{ {
Close(); Close();
@ -267,7 +267,7 @@ namespace IACore
#else // LINUX / POSIX #else // LINUX / POSIX
// 1. Open File // 1. Open File
fd_ = ::open(filepath.c_str(), O_RDONLY); fd_ = ::open(filepath.c_str(), O_RDWR);
if (fd_ == -1) if (fd_ == -1)
return false; return false;
@ -283,7 +283,7 @@ namespace IACore
// 3. mmap // 3. mmap
// PROT_READ: Read only // PROT_READ: Read only
// MAP_PRIVATE: Copy-on-write (safe if you accidentally modify, though we return const) // MAP_PRIVATE: Copy-on-write (safe if you accidentally modify, though we return const)
data_ = ::mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, fd_, 0); data_ = ::mmap(nullptr, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_, 0);
if (data_ == MAP_FAILED) if (data_ == MAP_FAILED)
{ {
data_ = nullptr; data_ = nullptr;

View File

@ -26,6 +26,8 @@
# include <bit> # include <bit>
# include <new> # include <new>
# include <span> # include <span>
# include <atomic>
# include <thread>
# include <limits> # include <limits>
# include <cstring> # include <cstring>
# include <cstddef> # include <cstddef>
@ -534,6 +536,9 @@ using StringStream = std::stringstream;
using HRClock = std::chrono::high_resolution_clock; using HRClock = std::chrono::high_resolution_clock;
using HRTimePoint = std::chrono::time_point<HRClock>; using HRTimePoint = std::chrono::time_point<HRClock>;
using Mutex = std::mutex;
using LockGuard = std::lock_guard<Mutex>;
template<typename... Args> using FormatterString = std::format_string<Args...>; template<typename... Args> using FormatterString = std::format_string<Args...>;
#endif #endif

View File

@ -40,6 +40,35 @@ namespace IACore
#endif #endif
} }
// ---------------------------------------------------------------------
// Async Execution
// ---------------------------------------------------------------------
// Returns a jthread.
// - Store it if you want to wait for it later (join).
// - If you destroy the returned jthread immediately, it will BLOCK (join) by design.
// - If you want "fire and forget", call .detach() on the returned thread.
STATIC std::jthread RunAsync(String cmd, String args, Function<VOID(StringView)> onOutputLine,
Function<VOID(tl::expected<INT32, String>)> onComplete)
{
// We capture arguments by VALUE (=) to ensure the thread owns its own copies of the strings.
return std::jthread([=, cmd = std::move(cmd), args = std::move(args)]() mutable {
tl::expected<INT32, String> result = tl::make_unexpected("Not started");
#if IA_PLATFORM_WINDOWS
result = RunWindows(cmd, args, onOutputLine);
#else
result = RunPosix(cmd, args, onOutputLine);
#endif
// Report final result to the callback
if (onComplete)
{
onComplete(std::move(result));
}
});
}
private: private:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Output Buffering Helper // Output Buffering Helper

View File

@ -0,0 +1,96 @@
// IACore-OSS; The Core Library for All IA Open Source Projects
// Copyright (C) 2025 IAS (ias@iasoft.dev)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <IACore/PCH.hpp>
#if IA_PLATFORM_WINDOWS
# include <winsock2.h>
# pragma comment(lib, "ws2_32.lib")
# define CLOSE_SOCKET(s) closesocket(s)
# define IS_VALID_SOCKET(s) (s != INVALID_SOCKET)
using SocketHandle = SOCKET;
#elif IA_PLATFORM_UNIX
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# define CLOSE_SOCKET(s) close(s)
# define IS_VALID_SOCKET(s) (s >= 0)
# define INVALID_SOCKET -1
using SocketHandle = int;
#else
# warning "IACore SocketOps is not supported on this platform."
#endif
namespace IACore
{
class SocketOps
{
public:
STATIC VOID Initialize()
{
#if IA_PLATFORM_WINDOWS
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
}
STATIC VOID Terminate()
{
#if IA_PLATFORM_WINDOWS
WSACleanup();
#endif
}
STATIC BOOL IsPortAvailableTCP(IN UINT16 port)
{
return IsPortAvailable(port, SOCK_STREAM);
}
STATIC BOOL IsPortAvailableUDP(IN UINT16 port)
{
return IsPortAvailable(port, SOCK_DGRAM);
}
private:
STATIC BOOL IsPortAvailable(IN UINT16 port, IN INT32 type)
{
SocketHandle sock = socket(AF_INET, type, IPPROTO_UDP);
if (!IS_VALID_SOCKET(sock))
return false;
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bool isFree = false;
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == 0)
isFree = true;
CLOSE_SOCKET(sock);
return isFree;
}
};
} // namespace IACore