fix clang-test crash

This commit is contained in:
mutouyun 2018-12-19 11:37:31 +08:00
parent 4c75b44547
commit 69449c0d4f
6 changed files with 46 additions and 33 deletions

View File

@ -21,6 +21,8 @@ IPC_EXPORT handle_t connect (char const * name);
IPC_EXPORT void disconnect(handle_t h); IPC_EXPORT void disconnect(handle_t h);
IPC_EXPORT std::size_t recv_count(handle_t h); IPC_EXPORT std::size_t recv_count(handle_t h);
IPC_EXPORT void clear_recv(handle_t h);
IPC_EXPORT void clear_recv(char const * name);
IPC_EXPORT bool send(handle_t h, void const * data, std::size_t size); IPC_EXPORT bool send(handle_t h, void const * data, std::size_t size);
IPC_EXPORT buff_t recv(handle_t h); IPC_EXPORT buff_t recv(handle_t h);

View File

@ -38,8 +38,8 @@ constexpr queue_t* queue_of(handle_t h) {
return static_cast<queue_t*>(h); return static_cast<queue_t*>(h);
} }
inline std::atomic_size_t* acc_of(queue_t* queue) { inline std::atomic_size_t* acc_of(queue_t* que) {
return reinterpret_cast<std::atomic_size_t*>(queue->elems()) - 1; return reinterpret_cast<std::atomic_size_t*>(que->elems()) - 1;
} }
} // internal-linkage } // internal-linkage
@ -72,11 +72,25 @@ void disconnect(handle_t h) {
} }
std::size_t recv_count(handle_t h) { std::size_t recv_count(handle_t h) {
auto queue = queue_of(h); auto que = queue_of(h);
if (queue == nullptr) { if (que == nullptr) {
return error_count; return error_count;
} }
return queue->conn_count(); return que->conn_count();
}
void clear_recv(handle_t h) {
auto* head = acc_of(queue_of(h));
if (head == nullptr) {
return;
}
std::memset(head, 0, sizeof(shm_info_t));
}
void clear_recv(char const * name) {
auto h = ipc::connect(name);
ipc::clear_recv(h);
ipc::disconnect(h);
} }
bool send(handle_t h, void const * data, std::size_t size) { bool send(handle_t h, void const * data, std::size_t size) {
@ -86,12 +100,12 @@ bool send(handle_t h, void const * data, std::size_t size) {
if (size == 0) { if (size == 0) {
return false; return false;
} }
auto queue = queue_of(h); auto que = queue_of(h);
if (queue == nullptr) { if (que == nullptr) {
return false; return false;
} }
// calc a new message id // calc a new message id
auto msg_id = acc_of(queue)->fetch_add(1, std::memory_order_relaxed); auto msg_id = acc_of(que)->fetch_add(1, std::memory_order_relaxed);
// push message fragment, one fragment size is data_length // push message fragment, one fragment size is data_length
int offset = 0; int offset = 0;
for (int i = 0; i < static_cast<int>(size / data_length); ++i, offset += data_length) { for (int i = 0; i < static_cast<int>(size / data_length); ++i, offset += data_length) {
@ -100,7 +114,7 @@ bool send(handle_t h, void const * data, std::size_t size) {
msg_id, { 0 } msg_id, { 0 }
}; };
std::memcpy(msg.data_, static_cast<byte_t const *>(data) + offset, data_length); std::memcpy(msg.data_, static_cast<byte_t const *>(data) + offset, data_length);
queue->push(msg); que->push(msg);
} }
// if remain > 0, this is the last message fragment // if remain > 0, this is the last message fragment
int remain = static_cast<int>(size) - offset; int remain = static_cast<int>(size) - offset;
@ -111,7 +125,7 @@ bool send(handle_t h, void const * data, std::size_t size) {
}; };
std::memcpy(msg.data_, static_cast<byte_t const *>(data) + offset, std::memcpy(msg.data_, static_cast<byte_t const *>(data) + offset,
static_cast<std::size_t>(remain)); static_cast<std::size_t>(remain));
queue->push(msg); que->push(msg);
} }
return true; return true;
} }
@ -124,10 +138,10 @@ buff_t recv(handle_t const * hs, std::size_t size) {
thread_local std::vector<queue_t*> q_arr(size); thread_local std::vector<queue_t*> q_arr(size);
q_arr.clear(); // make the size to 0 q_arr.clear(); // make the size to 0
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
auto queue = queue_of(hs[i]); auto que = queue_of(hs[i]);
if (queue == nullptr) continue; if (que == nullptr) continue;
queue->connect(); // wouldn't connect twice que->connect(); // wouldn't connect twice
q_arr.push_back(queue); q_arr.push_back(que);
} }
if (q_arr.empty()) { if (q_arr.empty()) {
return {}; return {};
@ -190,6 +204,7 @@ route::route(route&& rhs)
} }
route::~route() { route::~route() {
disconnect();
p_->clear(); p_->clear();
} }
@ -223,6 +238,7 @@ bool route::connect(char const * name) {
void route::disconnect() { void route::disconnect() {
ipc::disconnect(impl(p_)->h_); ipc::disconnect(impl(p_)->h_);
impl(p_)->h_ = nullptr;
} }
std::size_t route::recv_count() const { std::size_t route::recv_count() const {

View File

@ -10,20 +10,14 @@ namespace shm {
class handle::handle_ : public pimpl<handle_> { class handle::handle_ : public pimpl<handle_> {
public: public:
handle* t_ = nullptr; void* m_ = nullptr;
void* m_ = nullptr;
std::string n_ {}; std::string n_;
std::size_t s_ = 0; std::size_t s_ = 0;
handle_() = default;
handle_(handle* t) : t_{t} {}
~handle_() { t_->release(); }
}; };
handle::handle() handle::handle()
: p_(p_->make(this)) { : p_(p_->make()) {
} }
handle::handle(char const * name, std::size_t size) handle::handle(char const * name, std::size_t size)
@ -37,6 +31,7 @@ handle::handle(handle&& rhs)
} }
handle::~handle() { handle::~handle() {
release();
p_->clear(); p_->clear();
} }

View File

@ -47,8 +47,10 @@ template <>
struct test_verify<void> { struct test_verify<void> {
test_verify (int) {} test_verify (int) {}
void prepare (void*) {} void prepare (void*) {}
void push_data(int, ...) {}
void verify (int, int) {} void verify (int, int) {}
template <typename U>
void push_data(int, U&&) {}
}; };
template <typename T> template <typename T>
@ -70,10 +72,7 @@ void benchmark_prod_cons(T* cq) {
t = std::thread{[&, cid] { t = std::thread{[&, cid] {
vf.prepare(&t); vf.prepare(&t);
auto cn = tcq.connect(); auto cn = tcq.connect();
tcq.recv(cn, [&](auto&& msg) { vf.push_data(cid, msg); });
using namespace std::placeholders;
tcq.recv(cn, std::bind(&test_verify<V>::push_data, &vf, cid, _1));
tcq.disconnect(cn); tcq.disconnect(cn);
if (++fini != std::extent<decltype(consumers)>::value) return; if (++fini != std::extent<decltype(consumers)>::value) return;
sw.print_elapsed(N, M, Loops); sw.print_elapsed(N, M, Loops);

View File

@ -5,7 +5,6 @@
#include <new> #include <new>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <functional>
#include "circ_elem_array.h" #include "circ_elem_array.h"
#include "circ_queue.h" #include "circ_queue.h"

View File

@ -45,8 +45,7 @@ struct test_cq<ipc::route> {
test_cq(void*) test_cq(void*)
: conn_name_("test-ipc-route") { : conn_name_("test-ipc-route") {
auto watcher = connect(); ipc::clear_recv(conn_name_.c_str());
QCOMPARE(watcher.recv_count(), static_cast<std::size_t>(0));
} }
cn_t connect() { cn_t connect() {
@ -58,8 +57,8 @@ struct test_cq<ipc::route> {
} }
void wait_start(int M) { void wait_start(int M) {
auto watcher = connect(); auto watcher = ipc::connect(conn_name_.c_str());
while (watcher.recv_count() != static_cast<std::size_t>(M)) { while (ipc::recv_count(watcher) != static_cast<std::size_t>(M)) {
std::this_thread::yield(); std::this_thread::yield();
} }
} }
@ -257,6 +256,7 @@ void Unit::test_rw_lock() {
void Unit::test_send_recv() { void Unit::test_send_recv() {
auto h = ipc::connect("my-ipc"); auto h = ipc::connect("my-ipc");
QVERIFY(h != nullptr); QVERIFY(h != nullptr);
ipc::clear_recv(h);
char data[] = "hello ipc!"; char data[] = "hello ipc!";
QVERIFY(ipc::send(h, data, sizeof(data))); QVERIFY(ipc::send(h, data, sizeof(data)));
auto got = ipc::recv(h); auto got = ipc::recv(h);
@ -265,6 +265,8 @@ void Unit::test_send_recv() {
} }
void Unit::test_route() { void Unit::test_route() {
ipc::clear_recv("my-ipc-route");
auto wait_for_handshake = [](int id) { auto wait_for_handshake = [](int id) {
ipc::route cc { "my-ipc-route" }; ipc::route cc { "my-ipc-route" };
std::string cfm = "copy:" + std::to_string(id), ack = "re-" + cfm; std::string cfm = "copy:" + std::to_string(id), ack = "re-" + cfm;