Skip to content

Commit

Permalink
Merge pull request #93 from libsese/refactor-pimpl
Browse files Browse the repository at this point in the history
Refactor: pimpl (Plausibility check)
  • Loading branch information
SHIINASAMA authored Jan 6, 2025
2 parents 99af169 + d9cec16 commit b3fed76
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 209 deletions.
14 changes: 9 additions & 5 deletions sese/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ file(
"container/*.h"
)

file(GLOB_RECURSE UNIX_SRC "native/unix/*.cpp" "native/unix/*.h")
file(GLOB_RECURSE UNIX_SRC "internal/unix/*.cpp" "internal/unix/*.h" "native/unix/*.cpp" "native/unix/*.h")

file(GLOB_RECURSE INTERNAL_SRC "internal/net/*.cpp" "internal/net/*.h" "internal/service/*.cpp" "internal/service/*.h")

Expand Down Expand Up @@ -155,7 +155,7 @@ endif()
# Windows platform configuration
# ######################################################################################################################
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
file(GLOB_RECURSE NATIVE_WIN_SRC "native/win/*.cpp" "native/win/*.h")
file(GLOB_RECURSE NATIVE_WIN_SRC "internal/win/*.cpp" "native/win/*.cpp" "native/win/*.h")

target_sources(Core PRIVATE ${NATIVE_WIN_SRC})
target_compile_definitions(Core PRIVATE -D_WIN32_WINNT=0x0601)
Expand All @@ -182,7 +182,9 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(Core PRIVATE ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(Core PRIVATE ${CMAKE_DL_LIBS})

file(GLOB_RECURSE NATIVE_LINUX_SRC "native/linux/*.cpp" "native/linux/*.h")
file(GLOB_RECURSE NATIVE_LINUX_SRC "internal/linux/*.cpp" "internal/linux/*.h" "native/linux/*.cpp"
"native/linux/*.h"
)
target_sources(Core PRIVATE ${NATIVE_LINUX_SRC})

set_target_properties(Core PROPERTIES POSITION_INDEPENDENT_CODE ON)
Expand All @@ -195,8 +197,10 @@ endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries(Core PRIVATE ${COREFOUNDATION_FRAMEWORK} ${IOKIT_FRAMEWORK} ${CORESERVICES_FRAMEWORK})

file(GLOB_RECURSE NATIVE_DRAWIN_SRC "native/darwin/*.cpp" "native/darwin/*.h")
target_sources(Core PRIVATE ${NATIVE_DRAWIN_SRC})
file(GLOB_RECURSE NATIVE_DARWIN_SRC "internal/darwin/*.cpp" "internal/darwin/*.h" "native/darwin/*.cpp"
"native/darwin/*.h"
)
target_sources(Core PRIVATE ${NATIVE_DARWIN_SRC})
endif()

# ######################################################################################################################
Expand Down
6 changes: 3 additions & 3 deletions sese/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ namespace sys = sese::system;
#ifdef _WIN32
#pragma warning(disable : 4819)
#define SESE_PLATFORM_WINDOWS
#include "sese/native/win/Config.h"
#include "WindowsConfig.h"
#elif __linux__
#define SESE_PLATFORM_LINUX
#include "sese/native/linux/Config.h"
#include "LinuxConfig.h"
#elif __APPLE__
#define SESE_PLATFORM_APPLE
#include "sese/native/darwin/Config.h"
#include "DarwinConfig.h"
#endif

#define SESE_MARCO_END \
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
119 changes: 119 additions & 0 deletions sese/internal/unix/system/ProcessImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2025 libsese
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sese/system/Process.h>
#include <sese/Util.h>

#include <csignal>
#include <unistd.h>
#include <sys/wait.h>

using namespace sese::system;

class Process::ProcessImpl {
public:

static std::unique_ptr<ProcessImpl> createEx(const std::string &exec, const std::vector<std::string> &args) noexcept {
auto pid = fork();
if (pid > 0) {
// parent process
return std::make_unique<ProcessImpl>(pid);
} else if (pid == 0) {
// client process
auto c_args = new char *[args.size() + 2];
auto exec_string = new char[exec.size() + 1];
memcpy(exec_string, exec.c_str(), exec.size() + 1);
c_args[0] = exec_string;
int i = 1;
for (auto &arg: args) {
auto arg_string = new char[arg.size() + 1];
memcpy(arg_string, arg.c_str(), arg.size() + 1);
c_args[i] = arg_string;
i++;
}
c_args[args.size() + 1] = nullptr;

if (execvp(exec.c_str(), c_args) == -1) {
for (int i = 0; i < args.size() + 2; ++i) {
delete[] c_args[i];
}
delete[] c_args;
exit(errno);
return nullptr; // GCOVR_EXCL_LINE
} else {
// never reach
return nullptr; // GCOVR_EXCL_LINE
}
} else {
// failed to create
return nullptr; // GCOVR_EXCL_LINE
}
}

ProcessImpl(const sese::pid_t &pid) : pid(pid) {
}

static sese::pid_t getCurrentProcessId() noexcept {
return getpid();
}

int wait() const noexcept {
int status;
::waitpid(pid, &status, 0);
if (!WIFEXITED(status)) {
return WEXITSTATUS(status); // GCOVR_EXCL_LINE
} else {
return 0;
}
}

sese::pid_t getProcessId() const noexcept {
return pid;
}

bool kill() const noexcept {
return ::kill(pid, SIGKILL) == 0;
}

private:
sese::pid_t pid;
};

Process::~Process() {
}

sese::Result<Process::Ptr, sese::ErrorCode> Process::createEx(const std::string &exec, const std::vector<std::string> &args) noexcept {
if (auto impl = ProcessImpl::createEx(exec, args)) {
auto result = MAKE_UNIQUE_PRIVATE(Process);
result->process_impl = std::move(impl);
return Result<Ptr, ErrorCode>::success(std::move(result));
}
return Result<Ptr, ErrorCode>::error({getErrorCode(), getErrorString()});
}

sese::pid_t Process::getCurrentProcessId() noexcept {
return ProcessImpl::getCurrentProcessId();
}

int Process::wait() const noexcept {
return process_impl->wait();
}

bool Process::kill() const noexcept {
return process_impl->kill();
}

sese::pid_t Process::getProcessId() const noexcept {
return process_impl->getProcessId();
}
112 changes: 112 additions & 0 deletions sese/internal/win/system/ProcessImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2025 libsese
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sese/system/Process.h>
#include <sese/text/StringBuilder.h>
#include <sese/Util.h>

#include <windows.h>

using namespace sese::system;

class Process::ProcessImpl {
public:
using StartupInfo = std::unique_ptr<STARTUPINFO>;
using ProcessInfo = std::unique_ptr<PROCESS_INFORMATION>;
StartupInfo startupinfo;
ProcessInfo process_information;

static std::unique_ptr<ProcessImpl> createEx(const std::string &exec, const std::vector<std::string> &args) noexcept {
auto startup_info = std::make_unique<STARTUPINFO>();
auto process_info = std::make_unique<PROCESS_INFORMATION>();

text::StringBuilder builder;
builder << exec;
for (auto &arg: args) {
builder << " " << arg;
}
builder << '\0';
auto cmd_line = std::make_unique<char[]>(builder.size());
memcpy(cmd_line.get(), builder.buf(), builder.size());

bool rt = CreateProcessA(
nullptr,
cmd_line.get(),
nullptr,
nullptr,
false,
0,
nullptr,
nullptr,
startup_info.get(),
process_info.get()
);

if (rt) {
return std::make_unique<ProcessImpl>(std::move(startup_info), std::move(process_info));
}
return {};
}

static pid_t getCurrentProcessId() noexcept {
return GetCurrentProcessId();
}

int wait() const noexcept {
DWORD exit_code;
WaitForSingleObject(process_information->hProcess, INFINITE);
GetExitCodeProcess(process_information->hProcess, &exit_code);
return static_cast<int>(exit_code);
}

bool kill() const noexcept {
return TerminateProcess(process_information->hProcess, -1) != 0;
}

pid_t getProcessId() const noexcept {
return GetProcessId(process_information->hProcess);
}

ProcessImpl(StartupInfo startupinfo, ProcessInfo process_info)
: startupinfo(std::move(startupinfo)), process_information(std::move(process_info)) {
}
};

Process::~Process() {
}

sese::Result<Process::Ptr, sese::ErrorCode> Process::createEx(const std::string &exec, const std::vector<std::string> &args) noexcept {
if (auto impl = ProcessImpl::createEx(exec, args)) {
auto result = MAKE_UNIQUE_PRIVATE(Process);
result->process_impl = std::move(impl);
return Result<Ptr, ErrorCode>::success(std::move(result));
}
return Result<Ptr, ErrorCode>::error({getErrorCode(), getErrorString()});
}

sese::pid_t Process::getCurrentProcessId() noexcept {
return ProcessImpl::getCurrentProcessId();
}

int Process::wait() const noexcept {
return process_impl->wait();
}

bool Process::kill() const noexcept {
return process_impl->kill();
}

sese::pid_t Process::getProcessId() const noexcept {
return process_impl->getProcessId();
}
82 changes: 0 additions & 82 deletions sese/native/unix/system/Process.cpp

This file was deleted.

Loading

0 comments on commit b3fed76

Please sign in to comment.