mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
add: [ipc] implementation of shm
This commit is contained in:
parent
daa63049fe
commit
985ef22f64
17
src/libipc/platform/posix/def.h
Normal file
17
src/libipc/platform/posix/def.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* @file libipc/platform/posix/mmap.h
|
||||||
|
* @author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "libipc/def.h"
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
namespace posix {
|
||||||
|
|
||||||
|
enum : int {
|
||||||
|
failed = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace posix
|
||||||
|
LIBIPC_NAMESPACE_END_
|
||||||
@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file libipc/platform/posix/mmap.h
|
|
||||||
* @author mutouyun (orz@orzz.org)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include "libipc/shm.h"
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
|
||||||
|
|
||||||
struct mmap_handle {
|
|
||||||
std::string file;
|
|
||||||
std::size_t f_sz;
|
|
||||||
std::size_t f_of;
|
|
||||||
void *memp;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline int mmap_open_(mmap_handle *h_out, std::string const &file, int fd, int flags, std::size_t f_sz, std::size_t f_of) noexcept {
|
|
||||||
if (h_out == nullptr) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_END_
|
|
||||||
125
src/libipc/platform/posix/shm_impl.h
Normal file
125
src/libipc/platform/posix/shm_impl.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* @file libipc/platform/posix/shm_impl.h
|
||||||
|
* @author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "libimp/log.h"
|
||||||
|
#include "libimp/system.h"
|
||||||
|
|
||||||
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
|
#include "def.h"
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
using namespace ::LIBIMP_;
|
||||||
|
|
||||||
|
struct shm_handle {
|
||||||
|
std::string file;
|
||||||
|
std::size_t f_sz;
|
||||||
|
void *memp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://man7.org/linux/man-pages/man3/shm_open.3.html
|
||||||
|
* https://man7.org/linux/man-pages/man3/fstat.3p.html
|
||||||
|
* https://man7.org/linux/man-pages/man3/ftruncate.3p.html
|
||||||
|
* https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||||
|
*/
|
||||||
|
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
if (name.empty()) {
|
||||||
|
log.error("name is empty.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Open the object for read-write access.
|
||||||
|
int flag = O_RDWR;
|
||||||
|
switch (type) {
|
||||||
|
case mode::open:
|
||||||
|
size = 0;
|
||||||
|
break;
|
||||||
|
// The check for the existence of the object,
|
||||||
|
// and its creation if it does not exist, are performed atomically.
|
||||||
|
case mode::create:
|
||||||
|
flag |= O_CREAT | O_EXCL;
|
||||||
|
break;
|
||||||
|
// Create the shared memory object if it does not exist.
|
||||||
|
case mode::open | mode::create:
|
||||||
|
flag |= O_CREAT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.error("mode type is invalid. type = {}", type);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Create/Open POSIX shared memory bject
|
||||||
|
int fd = ::shm_open(name.c_str(), flag, S_IRUSR | S_IWUSR |
|
||||||
|
S_IRGRP | S_IWGRP |
|
||||||
|
S_IROTH | S_IWOTH);
|
||||||
|
if (fd == posix::failed) {
|
||||||
|
log.error("shm_open fails. error = {}", sys::error_msg(sys::error_code()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
/// @brief Try to get the size of this fd
|
||||||
|
struct stat st;
|
||||||
|
if (::fstat(fd, &st) == posix::failed) {
|
||||||
|
log.error("fstat fails. error = {}", sys::error_msg(sys::error_code()));
|
||||||
|
::shm_unlink(name.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
size = static_cast<std::size_t>(st.st_size);
|
||||||
|
/// @brief Truncate this fd to a specified length
|
||||||
|
} else if (::ftruncate(fd, size) != 0) {
|
||||||
|
log.error("ftruncate fails. error = {}", sys::error_msg(sys::error_code()));
|
||||||
|
::shm_unlink(name.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Creates a new mapping in the virtual address space of the calling process.
|
||||||
|
void *mem = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (mem == MAP_FAILED) {
|
||||||
|
log.error("mmap fails. error = {}", sys::error_msg(sys::error_code()));
|
||||||
|
::shm_unlink(name.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
::close(fd);
|
||||||
|
return new shm_handle{std::move(name), size, mem};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||||
|
*/
|
||||||
|
result_code shm_close(shm_t h) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
if (h == nullptr) {
|
||||||
|
log.error("shm handle is null.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto shm = static_cast<shm_handle *>(h);
|
||||||
|
if (shm->memp == nullptr) {
|
||||||
|
log.error("memory pointer is null.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (::munmap(shm->memp, shm->f_sz) == posix::failed) {
|
||||||
|
auto ec = sys::error_code();
|
||||||
|
log.error("munmap fails. error = {}", sys::error_msg(ec));
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
/// @brief no unlink the file.
|
||||||
|
delete shm;
|
||||||
|
return {true};
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_END_
|
||||||
@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @file libipc/platform/win/get_sa.h
|
||||||
|
* @author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <securitybaseapi.h>
|
#include <securitybaseapi.h>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @file libipc/platform/win/mmap.h
|
* @file libipc/platform/win/mmap_impl.h
|
||||||
* @author mutouyun (orz@orzz.org)
|
* @author mutouyun (orz@orzz.org)
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -150,31 +150,4 @@ void mmap_release(HANDLE h, LPCVOID mem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
::LIBIMP_::result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
|
||||||
LIBIMP_LOG_();
|
|
||||||
auto h = mmap_open(name, size, type);
|
|
||||||
if (h == NULL) {
|
|
||||||
log.error("mmap_open failed.");
|
|
||||||
return {nullptr, *sys::error_code()};
|
|
||||||
}
|
|
||||||
auto mem = mmap_memof(h);
|
|
||||||
if (mem == NULL) {
|
|
||||||
log.warning("mmap_memof failed.");
|
|
||||||
}
|
|
||||||
return new shm_handle{std::move(name), mmap_sizeof(mem), mem, h};
|
|
||||||
}
|
|
||||||
|
|
||||||
::LIBIMP_::result_code shm_close(shm_t h) noexcept {
|
|
||||||
LIBIMP_LOG_();
|
|
||||||
if (h == nullptr) {
|
|
||||||
log.error("shm handle is null.");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
auto shm = static_cast<shm_handle *>(h);
|
|
||||||
mmap_release(shm->h_fmap, shm->memp);
|
|
||||||
delete shm;
|
|
||||||
return {true};
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_END_
|
LIBIPC_NAMESPACE_END_
|
||||||
46
src/libipc/platform/win/shm_impl.h
Normal file
46
src/libipc/platform/win/shm_impl.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @file libipc/platform/win/shm_impl.h
|
||||||
|
* @author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "libimp/log.h"
|
||||||
|
#include "libimp/system.h"
|
||||||
|
|
||||||
|
#include "libipc/shm.h"
|
||||||
|
|
||||||
|
#include "mmap_impl.h"
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
using namespace ::LIBIMP_;
|
||||||
|
|
||||||
|
result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
auto h = mmap_open(name, size, type);
|
||||||
|
if (h == NULL) {
|
||||||
|
log.error("mmap_open failed.");
|
||||||
|
return {nullptr, *sys::error_code()};
|
||||||
|
}
|
||||||
|
auto mem = mmap_memof(h);
|
||||||
|
if (mem == NULL) {
|
||||||
|
log.warning("mmap_memof failed.");
|
||||||
|
}
|
||||||
|
return new shm_handle{std::move(name), mmap_sizeof(mem), mem, h};
|
||||||
|
}
|
||||||
|
|
||||||
|
result_code shm_close(shm_t h) noexcept {
|
||||||
|
LIBIMP_LOG_();
|
||||||
|
if (h == nullptr) {
|
||||||
|
log.error("shm handle is null.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto shm = static_cast<shm_handle *>(h);
|
||||||
|
mmap_release(shm->h_fmap, shm->memp);
|
||||||
|
delete shm;
|
||||||
|
return {true};
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBIPC_NAMESPACE_END_
|
||||||
@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @file libipc/platform/win/to_tchar.h
|
||||||
|
* @author mutouyun (orz@orzz.org)
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
#include "libimp/detect_plat.h"
|
#include "libimp/detect_plat.h"
|
||||||
#if defined(LIBIMP_OS_WIN)
|
#if defined(LIBIMP_OS_WIN)
|
||||||
#include "libipc/platform/win/mmap.h"
|
#include "libipc/platform/win/shm_impl.h"
|
||||||
#else
|
#else
|
||||||
#include "libipc/platform/posix/mmap.h"
|
#include "libipc/platform/posix/shm_impl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user