mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Testing with threads instead of processes under Windows.
This commit is contained in:
parent
8c643308dd
commit
264608b621
@ -21,7 +21,6 @@ A high-performance inter-process communication using shared memory on Linux/Wind
|
|||||||
- [ ] IPC:实现基本组件
|
- [ ] IPC:实现基本组件
|
||||||
- [x] 共享内存(需要作为后续组件的基础)
|
- [x] 共享内存(需要作为后续组件的基础)
|
||||||
- [x] 原子锁
|
- [x] 原子锁
|
||||||
- [ ] 进程对象
|
|
||||||
- [ ] 互斥量
|
- [ ] 互斥量
|
||||||
- [ ] 条件变量
|
- [ ] 条件变量
|
||||||
- [ ] 信号量
|
- [ ] 信号量
|
||||||
|
|||||||
@ -5,6 +5,14 @@ if(NOT MSVC)
|
|||||||
-Wno-attributes)
|
-Wno-attributes)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
# FetchContent_Declare(phnt
|
||||||
|
# GIT_REPOSITORY https://github.com/winsiderss/phnt.git
|
||||||
|
# GIT_TAG master
|
||||||
|
# )
|
||||||
|
# FetchContent_MakeAvailable(phnt)
|
||||||
|
# endif()
|
||||||
|
|
||||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc SRC_FILES)
|
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc SRC_FILES)
|
||||||
|
|
||||||
file(GLOB HEAD_FILES
|
file(GLOB HEAD_FILES
|
||||||
@ -47,6 +55,10 @@ else()
|
|||||||
target_link_libraries(${PROJECT_NAME} PUBLIC imp pmr)
|
target_link_libraries(${PROJECT_NAME} PUBLIC imp pmr)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
# target_link_libraries(${PROJECT_NAME} PUBLIC phnt)
|
||||||
|
# endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS ${PROJECT_NAME}
|
TARGETS ${PROJECT_NAME}
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
|
|||||||
71
src/libipc/platform/win/process_impl.h
Normal file
71
src/libipc/platform/win/process_impl.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* \file libipc/platform/win/process_impl.h
|
||||||
|
* \author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <phnt_windows.h>
|
||||||
|
#include <phnt.h>
|
||||||
|
|
||||||
|
#include "libimp/log.h"
|
||||||
|
#include "libipc/process.h"
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
using namespace ::LIBIMP;
|
||||||
|
|
||||||
|
/// \brief Experimental fork() on Windows.
|
||||||
|
/// \see https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6
|
||||||
|
/// https://github.com/huntandhackett/process-cloning
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
typedef SSIZE_T pid_t;
|
||||||
|
|
||||||
|
pid_t fork() {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
|
||||||
|
RTL_USER_PROCESS_INFORMATION process_info;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* lets do this */
|
||||||
|
status = RtlCloneUserProcess(RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES
|
||||||
|
, NULL, NULL, NULL, &process_info);
|
||||||
|
if (status == STATUS_PROCESS_CLONED) {
|
||||||
|
// Executing inside the clone...
|
||||||
|
// Re-attach to the parent's console to be able to write to it
|
||||||
|
FreeConsole();
|
||||||
|
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// Executing inside the original (parent) process...
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
log.error("failed: RtlCloneUserProcess(...)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (pid_t)process_info.ProcessHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WNOHANG 1 /* Don't block waiting. */
|
||||||
|
|
||||||
|
/// \see https://man7.org/linux/man-pages/man3/wait.3p.html
|
||||||
|
/// https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntwaitforsingleobject
|
||||||
|
pid_t waitpid(pid_t pid, int */*status*/, int options) {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
if (pid == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (options & WNOHANG) {
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
NTSTATUS status = NtWaitForSingleObject((HANDLE)pid, FALSE, NULL);
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
log.error("failed: NtWaitForSingleObject(...)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
LIBIPC_NAMESPACE_END_
|
||||||
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "libipc/shm.h"
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
|
#include "test_util.h"
|
||||||
|
|
||||||
TEST(shm, open_close) {
|
TEST(shm, open_close) {
|
||||||
EXPECT_FALSE(ipc::shm_open("hello-ipc-shm", 1024, ipc::mode::none));
|
EXPECT_FALSE(ipc::shm_open("hello-ipc-shm", 1024, ipc::mode::none));
|
||||||
|
|
||||||
@ -76,6 +78,22 @@ TEST(shm, shared_memory) {
|
|||||||
EXPECT_TRUE(ipc::shm_close(*shm_r));
|
EXPECT_TRUE(ipc::shm_close(*shm_r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(shm, process) {
|
||||||
|
ipc::shared_memory shm{"ipc-shared-memory-process1", 333};
|
||||||
|
ASSERT_TRUE(shm.valid());
|
||||||
|
*shm.as<int>() = 4321;
|
||||||
|
|
||||||
|
auto r1 = test::subproc([] {
|
||||||
|
ipc::shared_memory shm{"ipc-shared-memory-process1"};
|
||||||
|
ASSERT_TRUE(shm.valid());
|
||||||
|
EXPECT_EQ(*shm.as<int>(), 4321);
|
||||||
|
*shm.as<int>() = 1234;
|
||||||
|
});
|
||||||
|
|
||||||
|
test::join_subproc(r1);
|
||||||
|
EXPECT_EQ(*shm.as<int>(), 1234);
|
||||||
|
}
|
||||||
|
|
||||||
#include <libimp/detect_plat.h>
|
#include <libimp/detect_plat.h>
|
||||||
#if /*defined(LIBIMP_OS_LINUX)*/ 0
|
#if /*defined(LIBIMP_OS_LINUX)*/ 0
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -87,8 +105,6 @@ TEST(shm, shared_memory) {
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "test_util.h"
|
|
||||||
|
|
||||||
TEST(shm, pipe) {
|
TEST(shm, pipe) {
|
||||||
auto writer = test::subproc([] {
|
auto writer = test::subproc([] {
|
||||||
mkfifo("/tmp/shm-pipe.w", S_IFIFO|0666);
|
mkfifo("/tmp/shm-pipe.w", S_IFIFO|0666);
|
||||||
|
|||||||
@ -6,7 +6,9 @@
|
|||||||
# include <sys/wait.h>
|
# include <sys/wait.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#else
|
#else
|
||||||
# define pid_t int
|
# include <Windows.h>
|
||||||
|
# include <process.h>
|
||||||
|
# define pid_t uintptr_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@ -15,7 +17,7 @@
|
|||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
pid_t subproc(Fn&& fn) {
|
pid_t subproc(Fn &&fn) {
|
||||||
#ifndef LIBIMP_OS_WIN
|
#ifndef LIBIMP_OS_WIN
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
@ -31,14 +33,23 @@ pid_t subproc(Fn&& fn) {
|
|||||||
}
|
}
|
||||||
return pid;
|
return pid;
|
||||||
#else
|
#else
|
||||||
return -1;
|
auto runner = [](void* pparam) {
|
||||||
|
auto fn = reinterpret_cast<std::decay_t<Fn> *>(pparam);
|
||||||
|
(*fn)();
|
||||||
|
};
|
||||||
|
return _beginthread(runner, 0, (void *)&fn);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void join_subproc(pid_t pid) {
|
inline void join_subproc(pid_t pid) {
|
||||||
|
if (pid == -1) return;
|
||||||
#ifndef LIBIMP_OS_WIN
|
#ifndef LIBIMP_OS_WIN
|
||||||
int ret_code;
|
int ret_code;
|
||||||
waitpid(pid, &ret_code, 0);
|
waitpid(pid, &ret_code, 0);
|
||||||
|
#else
|
||||||
|
HANDLE hThread = reinterpret_cast<HANDLE>(pid);
|
||||||
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
|
CloseHandle(hThread);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user