Skip to content

Commit 5071fb5

Browse files
committed
Added a cleanup interface for shared memory handles
1 parent 8054906 commit 5071fb5

File tree

8 files changed

+273
-201
lines changed

8 files changed

+273
-201
lines changed

include/libipc/pool_alloc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ namespace mem {
1111

1212
class IPC_EXPORT pool_alloc {
1313
public:
14-
static void* alloc(std::size_t size);
15-
static void free (void* p, std::size_t size);
14+
static void* alloc(std::size_t size) noexcept;
15+
static void free (void* p, std::size_t size) noexcept;
1616
};
1717

1818
////////////////////////////////////////////////////////////////

include/libipc/shm.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ enum : unsigned {
1717

1818
IPC_EXPORT id_t acquire(char const * name, std::size_t size, unsigned mode = create | open);
1919
IPC_EXPORT void * get_mem(id_t id, std::size_t * size);
20-
IPC_EXPORT std::int32_t release(id_t id);
21-
IPC_EXPORT void remove (id_t id);
22-
IPC_EXPORT void remove (char const * name);
20+
IPC_EXPORT std::int32_t release(id_t id) noexcept;
21+
IPC_EXPORT void remove (id_t id) noexcept;
22+
IPC_EXPORT void remove (char const * name) noexcept;
2323

2424
IPC_EXPORT std::int32_t get_ref(id_t id);
2525
IPC_EXPORT void sub_ref(id_t id);
@@ -45,6 +45,10 @@ class IPC_EXPORT handle {
4545
bool acquire(char const * name, std::size_t size, unsigned mode = create | open);
4646
std::int32_t release();
4747

48+
// Clean the handle file.
49+
void clear() noexcept;
50+
static void clear_storage(char const * name) noexcept;
51+
4852
void* get() const;
4953

5054
void attach(id_t);

src/libipc/memory/alloc.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ namespace mem {
1919

2020
class static_alloc {
2121
public:
22-
static void swap(static_alloc&) {}
22+
static void swap(static_alloc&) noexcept {}
2323

24-
static void* alloc(std::size_t size) {
24+
static void* alloc(std::size_t size) noexcept {
2525
return size ? std::malloc(size) : nullptr;
2626
}
2727

28-
static void free(void* p) {
28+
static void free(void* p) noexcept {
2929
std::free(p);
3030
}
3131

32-
static void free(void* p, std::size_t /*size*/) {
32+
static void free(void* p, std::size_t /*size*/) noexcept {
3333
free(p);
3434
}
3535
};

src/libipc/platform/posix/shm_posix.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void * get_mem(id_t id, std::size_t * size) {
153153
return mem;
154154
}
155155

156-
std::int32_t release(id_t id) {
156+
std::int32_t release(id_t id) noexcept {
157157
if (id == nullptr) {
158158
ipc::error("fail release: invalid id (null)\n");
159159
return -1;
@@ -175,7 +175,7 @@ std::int32_t release(id_t id) {
175175
return ret;
176176
}
177177

178-
void remove(id_t id) {
178+
void remove(id_t id) noexcept {
179179
if (id == nullptr) {
180180
ipc::error("fail remove: invalid id (null)\n");
181181
return;

src/libipc/pool_alloc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
namespace ipc {
66
namespace mem {
77

8-
void* pool_alloc::alloc(std::size_t size) {
8+
void* pool_alloc::alloc(std::size_t size) noexcept {
99
return async_pool_alloc::alloc(size);
1010
}
1111

12-
void pool_alloc::free(void* p, std::size_t size) {
12+
void pool_alloc::free(void* p, std::size_t size) noexcept {
1313
async_pool_alloc::free(p, size);
1414
}
1515

src/libipc/shm.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ std::int32_t handle::release() {
8989
return shm::release(detach());
9090
}
9191

92+
void handle::clear() noexcept {
93+
if (impl(p_)->id_ == nullptr) return;
94+
shm::remove(detach());
95+
}
96+
97+
void handle::clear_storage(char const * name) noexcept {
98+
if (name == nullptr) {
99+
return;
100+
}
101+
shm::remove(name);
102+
}
103+
92104
void* handle::get() const {
93105
return impl(p_)->m_;
94106
}

test/test.h

Lines changed: 110 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,110 @@
1-
#pragma once
2-
3-
#include <iostream>
4-
#include <atomic>
5-
#include <thread>
6-
#include <string>
7-
#include <memory>
8-
#include <mutex>
9-
#include <utility>
10-
11-
#include "gtest/gtest.h"
12-
13-
#include "capo/stopwatch.hpp"
14-
15-
#include "thread_pool.h"
16-
17-
namespace ipc_ut {
18-
19-
template <typename Dur>
20-
struct unit;
21-
22-
template <> struct unit<std::chrono::nanoseconds> {
23-
constexpr static char const * str() noexcept {
24-
return "ns";
25-
}
26-
};
27-
28-
template <> struct unit<std::chrono::microseconds> {
29-
constexpr static char const * str() noexcept {
30-
return "us";
31-
}
32-
};
33-
34-
template <> struct unit<std::chrono::milliseconds> {
35-
constexpr static char const * str() noexcept {
36-
return "ms";
37-
}
38-
};
39-
40-
template <> struct unit<std::chrono::seconds> {
41-
constexpr static char const * str() noexcept {
42-
return "sec";
43-
}
44-
};
45-
46-
struct test_stopwatch {
47-
capo::stopwatch<> sw_;
48-
std::atomic_flag started_ = ATOMIC_FLAG_INIT;
49-
50-
void start() {
51-
if (!started_.test_and_set()) {
52-
sw_.start();
53-
}
54-
}
55-
56-
template <typename ToDur = std::chrono::nanoseconds>
57-
void print_elapsed(int N, int Loops, char const * message = "") {
58-
auto ts = sw_.elapsed<ToDur>();
59-
std::cout << "[" << N << ", \t" << Loops << "] " << message << "\t"
60-
<< (double(ts) / double(Loops)) << " " << unit<ToDur>::str() << std::endl;
61-
}
62-
63-
template <int Factor, typename ToDur = std::chrono::nanoseconds>
64-
void print_elapsed(int N, int M, int Loops, char const * message = "") {
65-
auto ts = sw_.elapsed<ToDur>();
66-
std::cout << "[" << N << "-" << M << ", \t" << Loops << "] " << message << "\t"
67-
<< (double(ts) / double(Factor ? (Loops * Factor) : (Loops * N))) << " " << unit<ToDur>::str() << std::endl;
68-
}
69-
70-
template <typename ToDur = std::chrono::nanoseconds>
71-
void print_elapsed(int N, int M, int Loops, char const * message = "") {
72-
print_elapsed<0, ToDur>(N, M, Loops, message);
73-
}
74-
};
75-
76-
inline static thread_pool & sender() {
77-
static thread_pool pool;
78-
return pool;
79-
}
80-
81-
inline static thread_pool & reader() {
82-
static thread_pool pool;
83-
return pool;
84-
}
85-
86-
} // namespace ipc_ut
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <atomic>
5+
#include <thread>
6+
#include <string>
7+
#include <memory>
8+
#include <mutex>
9+
#include <utility>
10+
11+
#include "gtest/gtest.h"
12+
13+
#include "capo/stopwatch.hpp"
14+
15+
#include "thread_pool.h"
16+
17+
#include "libipc/platform/detail.h"
18+
#ifdef IPC_OS_LINUX_
19+
#include <fcntl.h> // ::open
20+
#endif
21+
22+
namespace ipc_ut {
23+
24+
template <typename Dur>
25+
struct unit;
26+
27+
template <> struct unit<std::chrono::nanoseconds> {
28+
constexpr static char const * str() noexcept {
29+
return "ns";
30+
}
31+
};
32+
33+
template <> struct unit<std::chrono::microseconds> {
34+
constexpr static char const * str() noexcept {
35+
return "us";
36+
}
37+
};
38+
39+
template <> struct unit<std::chrono::milliseconds> {
40+
constexpr static char const * str() noexcept {
41+
return "ms";
42+
}
43+
};
44+
45+
template <> struct unit<std::chrono::seconds> {
46+
constexpr static char const * str() noexcept {
47+
return "sec";
48+
}
49+
};
50+
51+
struct test_stopwatch {
52+
capo::stopwatch<> sw_;
53+
std::atomic_flag started_ = ATOMIC_FLAG_INIT;
54+
55+
void start() {
56+
if (!started_.test_and_set()) {
57+
sw_.start();
58+
}
59+
}
60+
61+
template <typename ToDur = std::chrono::nanoseconds>
62+
void print_elapsed(int N, int Loops, char const * message = "") {
63+
auto ts = sw_.elapsed<ToDur>();
64+
std::cout << "[" << N << ", \t" << Loops << "] " << message << "\t"
65+
<< (double(ts) / double(Loops)) << " " << unit<ToDur>::str() << std::endl;
66+
}
67+
68+
template <int Factor, typename ToDur = std::chrono::nanoseconds>
69+
void print_elapsed(int N, int M, int Loops, char const * message = "") {
70+
auto ts = sw_.elapsed<ToDur>();
71+
std::cout << "[" << N << "-" << M << ", \t" << Loops << "] " << message << "\t"
72+
<< (double(ts) / double(Factor ? (Loops * Factor) : (Loops * N))) << " " << unit<ToDur>::str() << std::endl;
73+
}
74+
75+
template <typename ToDur = std::chrono::nanoseconds>
76+
void print_elapsed(int N, int M, int Loops, char const * message = "") {
77+
print_elapsed<0, ToDur>(N, M, Loops, message);
78+
}
79+
};
80+
81+
inline static thread_pool & sender() {
82+
static thread_pool pool;
83+
return pool;
84+
}
85+
86+
inline static thread_pool & reader() {
87+
static thread_pool pool;
88+
return pool;
89+
}
90+
91+
#ifdef IPC_OS_LINUX_
92+
inline bool check_exist(char const *name) noexcept {
93+
int fd = ::open((std::string{"/dev/shm/__IPC_SHM__"} + name).c_str(), O_RDONLY);
94+
if (fd == -1) {
95+
return false;
96+
}
97+
::close(fd);
98+
return true;
99+
}
100+
#endif
101+
102+
inline bool expect_exist(char const *name, bool expected) noexcept {
103+
#ifdef IPC_OS_LINUX_
104+
return ipc_ut::check_exist(name) == expected;
105+
#else
106+
return true;
107+
#endif
108+
}
109+
110+
} // namespace ipc_ut

0 commit comments

Comments
 (0)