Skip to content

Commit fbf1c89

Browse files
authored
Merge pull request #63 from mutouyun/develop
Develop
2 parents d80bea9 + a457a89 commit fbf1c89

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1915
-1536
lines changed

.travis.yml

-31
This file was deleted.

CMakeLists.txt

+13-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if(NOT MSVC)
1313
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
1414
endif()
1515

16-
if (MSVC AND LIBIPC_USE_STATIC_CRT)
16+
if (MSVC)
1717
set(CompilerFlags
1818
CMAKE_CXX_FLAGS
1919
CMAKE_CXX_FLAGS_DEBUG
@@ -22,9 +22,17 @@ if (MSVC AND LIBIPC_USE_STATIC_CRT)
2222
CMAKE_C_FLAGS_DEBUG
2323
CMAKE_C_FLAGS_RELEASE
2424
)
25-
foreach(CompilerFlag ${CompilerFlags})
26-
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
27-
endforeach()
25+
if (LIBIPC_USE_STATIC_CRT)
26+
foreach(CompilerFlag ${CompilerFlags})
27+
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
28+
string(REPLACE "/MDd" "/MTd" ${CompilerFlag} "${${CompilerFlag}}")
29+
endforeach()
30+
else()
31+
foreach(CompilerFlag ${CompilerFlags})
32+
string(REPLACE "/MT" "/MD" ${CompilerFlag} "${${CompilerFlag}}")
33+
string(REPLACE "/MTd" "/MDd" ${CompilerFlag} "${${CompilerFlag}}")
34+
endforeach()
35+
endif()
2836
endif()
2937

3038
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
@@ -50,6 +58,7 @@ endif()
5058
if (LIBIPC_BUILD_DEMOS)
5159
add_subdirectory(demo/chat)
5260
add_subdirectory(demo/msg_que)
61+
add_subdirectory(demo/send_recv)
5362
endif()
5463

5564
install(

demo/msg_que/main.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ constexpr char const mode_r__[] = "r";
2020
constexpr std::size_t const min_sz = 128;
2121
constexpr std::size_t const max_sz = 1024 * 16;
2222

23-
std::atomic<bool> is_quit__{ false };
24-
std::atomic<std::size_t> size_counter__{ 0 };
23+
std::atomic<bool> is_quit__ {false};
24+
std::atomic<std::size_t> size_counter__ {0};
2525

2626
using msg_que_t = ipc::chan<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>;
2727

@@ -127,10 +127,10 @@ int main(int argc, char ** argv) {
127127
::signal(SIGHUP , exit);
128128
#endif
129129

130-
if (std::string{ argv[1] } == mode_s__) {
130+
std::string mode {argv[1]};
131+
if (mode == mode_s__) {
131132
do_send();
132-
}
133-
else if (std::string{ argv[1] } == mode_r__) {
133+
} else if (mode == mode_r__) {
134134
do_recv();
135135
}
136136
return 0;

demo/send_recv/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
project(send_recv)
2+
3+
include_directories(
4+
${LIBIPC_PROJECT_DIR}/3rdparty)
5+
6+
file(GLOB SRC_FILES ./*.cpp)
7+
file(GLOB HEAD_FILES ./*.h)
8+
9+
add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES})
10+
11+
target_link_libraries(${PROJECT_NAME} ipc)

demo/send_recv/main.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
#include <signal.h>
3+
4+
#include <iostream>
5+
#include <string>
6+
#include <thread>
7+
#include <chrono>
8+
#include <atomic>
9+
10+
#include "libipc/ipc.h"
11+
12+
namespace {
13+
14+
std::atomic<bool> is_quit__ {false};
15+
ipc::channel *ipc__ = nullptr;
16+
17+
void do_send(int size, int interval) {
18+
ipc::channel ipc {"ipc", ipc::sender};
19+
ipc__ = &ipc;
20+
std::string buffer(size, 'A');
21+
while (!is_quit__.load(std::memory_order_acquire)) {
22+
std::cout << "send size: " << buffer.size() + 1 << "\n";
23+
ipc.send(buffer, 0/*tm*/);
24+
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
25+
}
26+
}
27+
28+
void do_recv(int interval) {
29+
ipc::channel ipc {"ipc", ipc::receiver};
30+
ipc__ = &ipc;
31+
while (!is_quit__.load(std::memory_order_acquire)) {
32+
ipc::buff_t recv;
33+
for (int k = 1; recv.empty(); ++k) {
34+
std::cout << "recv waiting... " << k << "\n";
35+
recv = ipc.recv(interval);
36+
if (is_quit__.load(std::memory_order_acquire)) return;
37+
}
38+
std::cout << "recv size: " << recv.size() << "\n";
39+
}
40+
}
41+
42+
} // namespace
43+
44+
int main(int argc, char ** argv) {
45+
if (argc < 3) return -1;
46+
47+
auto exit = [](int) {
48+
is_quit__.store(true, std::memory_order_release);
49+
if (ipc__ != nullptr) ipc__->disconnect();
50+
};
51+
::signal(SIGINT , exit);
52+
::signal(SIGABRT , exit);
53+
::signal(SIGSEGV , exit);
54+
::signal(SIGTERM , exit);
55+
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || \
56+
defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \
57+
defined(WINCE) || defined(_WIN32_WCE)
58+
::signal(SIGBREAK, exit);
59+
#else
60+
::signal(SIGHUP , exit);
61+
#endif
62+
63+
std::string mode {argv[1]};
64+
if (mode == "send") {
65+
if (argc < 4) return -1;
66+
do_send(std::stoi(argv[2]) /*size*/,
67+
std::stoi(argv[3]) /*interval*/);
68+
} else if (mode == "recv") {
69+
do_recv(std::stoi(argv[2]) /*interval*/);
70+
}
71+
return 0;
72+
}

include/libipc/condition.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include <cstdint> // std::uint64_t
4+
5+
#include "libipc/export.h"
6+
#include "libipc/def.h"
7+
#include "libipc/mutex.h"
8+
9+
namespace ipc {
10+
namespace sync {
11+
12+
class IPC_EXPORT condition {
13+
condition(condition const &) = delete;
14+
condition &operator=(condition const &) = delete;
15+
16+
public:
17+
condition();
18+
explicit condition(char const *name);
19+
~condition();
20+
21+
void const *native() const noexcept;
22+
void *native() noexcept;
23+
24+
bool valid() const noexcept;
25+
26+
bool open(char const *name) noexcept;
27+
void close() noexcept;
28+
29+
bool wait(ipc::sync::mutex &mtx, std::uint64_t tm = ipc::invalid_value) noexcept;
30+
bool notify() noexcept;
31+
bool broadcast() noexcept;
32+
33+
private:
34+
class condition_;
35+
condition_* p_;
36+
};
37+
38+
} // namespace sync
39+
} // namespace ipc

include/libipc/def.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@ using uint_t = typename uint<N>::type;
2525

2626
// constants
2727

28+
enum : std::uint32_t {
29+
invalid_value = (std::numeric_limits<std::uint32_t>::max)(),
30+
default_timeout = 100, // ms
31+
};
32+
2833
enum : std::size_t {
29-
invalid_value = (std::numeric_limits<std::size_t>::max)(),
3034
data_length = 64,
3135
large_msg_limit = data_length,
3236
large_msg_align = 1024,
3337
large_msg_cache = 32,
34-
default_timeout = 100 // ms
3538
};
3639

3740
enum class relat { // multiplicity of the relationship

include/libipc/ipc.h

+13-13
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ struct IPC_EXPORT chan_impl {
2727
static char const * name(ipc::handle_t h);
2828

2929
static std::size_t recv_count(ipc::handle_t h);
30-
static bool wait_for_recv(ipc::handle_t h, std::size_t r_count, std::size_t tm);
30+
static bool wait_for_recv(ipc::handle_t h, std::size_t r_count, std::uint64_t tm);
3131

32-
static bool send(ipc::handle_t h, void const * data, std::size_t size, std::size_t tm);
33-
static buff_t recv(ipc::handle_t h, std::size_t tm);
32+
static bool send(ipc::handle_t h, void const * data, std::size_t size, std::uint64_t tm);
33+
static buff_t recv(ipc::handle_t h, std::uint64_t tm);
3434

35-
static bool try_send(ipc::handle_t h, void const * data, std::size_t size, std::size_t tm);
35+
static bool try_send(ipc::handle_t h, void const * data, std::size_t size, std::uint64_t tm);
3636
static buff_t try_recv(ipc::handle_t h);
3737
};
3838

@@ -120,41 +120,41 @@ class chan_wrapper {
120120
return detail_t::recv_count(h_);
121121
}
122122

123-
bool wait_for_recv(std::size_t r_count, std::size_t tm = invalid_value) const {
123+
bool wait_for_recv(std::size_t r_count, std::uint64_t tm = invalid_value) const {
124124
return detail_t::wait_for_recv(h_, r_count, tm);
125125
}
126126

127-
static bool wait_for_recv(char const * name, std::size_t r_count, std::size_t tm = invalid_value) {
127+
static bool wait_for_recv(char const * name, std::size_t r_count, std::uint64_t tm = invalid_value) {
128128
return chan_wrapper(name).wait_for_recv(r_count, tm);
129129
}
130130

131131
/**
132132
* If timeout, this function would call 'force_push' to send the data forcibly.
133133
*/
134-
bool send(void const * data, std::size_t size, std::size_t tm = default_timeout) {
134+
bool send(void const * data, std::size_t size, std::uint64_t tm = default_timeout) {
135135
return detail_t::send(h_, data, size, tm);
136136
}
137-
bool send(buff_t const & buff, std::size_t tm = default_timeout) {
137+
bool send(buff_t const & buff, std::uint64_t tm = default_timeout) {
138138
return this->send(buff.data(), buff.size(), tm);
139139
}
140-
bool send(std::string const & str, std::size_t tm = default_timeout) {
140+
bool send(std::string const & str, std::uint64_t tm = default_timeout) {
141141
return this->send(str.c_str(), str.size() + 1, tm);
142142
}
143143

144144
/**
145145
* If timeout, this function would just return false.
146146
*/
147-
bool try_send(void const * data, std::size_t size, std::size_t tm = default_timeout) {
147+
bool try_send(void const * data, std::size_t size, std::uint64_t tm = default_timeout) {
148148
return detail_t::try_send(h_, data, size, tm);
149149
}
150-
bool try_send(buff_t const & buff, std::size_t tm = default_timeout) {
150+
bool try_send(buff_t const & buff, std::uint64_t tm = default_timeout) {
151151
return this->try_send(buff.data(), buff.size(), tm);
152152
}
153-
bool try_send(std::string const & str, std::size_t tm = default_timeout) {
153+
bool try_send(std::string const & str, std::uint64_t tm = default_timeout) {
154154
return this->try_send(str.c_str(), str.size() + 1, tm);
155155
}
156156

157-
buff_t recv(std::size_t tm = invalid_value) {
157+
buff_t recv(std::uint64_t tm = invalid_value) {
158158
return detail_t::recv(h_, tm);
159159
}
160160

include/libipc/mutex.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include <cstdint> // std::uint64_t
4+
#include <system_error>
5+
6+
#include "libipc/export.h"
7+
#include "libipc/def.h"
8+
9+
namespace ipc {
10+
namespace sync {
11+
12+
class IPC_EXPORT mutex {
13+
mutex(mutex const &) = delete;
14+
mutex &operator=(mutex const &) = delete;
15+
16+
public:
17+
mutex();
18+
explicit mutex(char const *name);
19+
~mutex();
20+
21+
void const *native() const noexcept;
22+
void *native() noexcept;
23+
24+
bool valid() const noexcept;
25+
26+
bool open(char const *name) noexcept;
27+
void close() noexcept;
28+
29+
bool lock(std::uint64_t tm = ipc::invalid_value) noexcept;
30+
bool try_lock() noexcept(false); // std::system_error
31+
bool unlock() noexcept;
32+
33+
private:
34+
class mutex_;
35+
mutex_* p_;
36+
};
37+
38+
} // namespace sync
39+
} // namespace ipc

include/libipc/rw_lock.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ inline void yield(K& k) noexcept {
7272
++k;
7373
}
7474

75-
template <std::size_t N = 4096, typename K, typename F>
75+
template <std::size_t N = 32, typename K, typename F>
7676
inline void sleep(K& k, F&& f) {
7777
if (k < static_cast<K>(N)) {
7878
std::this_thread::yield();
@@ -84,7 +84,7 @@ inline void sleep(K& k, F&& f) {
8484
++k;
8585
}
8686

87-
template <std::size_t N = 4096, typename K>
87+
template <std::size_t N = 32, typename K>
8888
inline void sleep(K& k) {
8989
sleep<N>(k, [] {
9090
std::this_thread::sleep_for(std::chrono::milliseconds(1));

0 commit comments

Comments
 (0)