| | |
| | | using namespace std::chrono; |
| | | // using namespace std::chrono_literals; |
| | | |
| | | BOOST_AUTO_TEST_CASE(MutexTest) |
| | | { |
| | | // typedef robust::CasMutex<true> RobustMutex; |
| | | typedef MutexWithPidCheck RobustMutex; |
| | | |
| | | for (int i = 0; i < 20; ++i) { |
| | | int size = i; |
| | | int left = size & 7; |
| | | int rsize = size + ((8 - left) & 7); |
| | | printf("size: %3d, rsize: %3d\n", size, rsize); |
| | | } |
| | | SharedMemory &shm = TestShm(); |
| | | // shm.Remove(); |
| | | // return; |
| | | GlobalInit(shm); |
| | | |
| | | const std::string mtx_name("test_mutex"); |
| | | const std::string int_name("test_int"); |
| | | auto mtx = shm.FindOrCreate<RobustMutex>(mtx_name); |
| | | auto pi = shm.FindOrCreate<int>(int_name, 100); |
| | | |
| | | std::mutex m; |
| | | typedef std::chrono::steady_clock Clock; |
| | | auto Now = []() { return Clock::now().time_since_epoch(); }; |
| | | if (pi) { |
| | | auto old = *pi; |
| | | printf("int : %d, add1: %d\n", old, ++*pi); |
| | | } |
| | | |
| | | { |
| | | boost::timer::auto_cpu_timer timer; |
| | | const int ntimes = 1000 * 1000; |
| | | printf("test lock/unlock %d times: ", ntimes); |
| | | RobustMutex mutex; |
| | | auto Lock = [&]() { |
| | | for (int i = 0; i < ntimes; ++i) { |
| | | mutex.lock(); |
| | | mutex.unlock(); |
| | | } |
| | | }; |
| | | std::thread t1(Lock), t2(Lock); |
| | | t1.join(); |
| | | t2.join(); |
| | | } |
| | | |
| | | auto MSFromNow = [](const int ms) { |
| | | using namespace boost::posix_time; |
| | | ptime cur = boost::posix_time::microsec_clock::universal_time(); |
| | | return cur + millisec(ms); |
| | | }; |
| | | |
| | | auto TryLock = [&]() { |
| | | if (mtx->try_lock()) { |
| | | printf("try_lock ok\n"); |
| | | return true; |
| | | } else { |
| | | printf("try_lock failed\n"); |
| | | return false; |
| | | } |
| | | }; |
| | | auto Unlock = [&]() { |
| | | mtx->unlock(); |
| | | printf("unlocked\n"); |
| | | }; |
| | | |
| | | if (mtx) { |
| | | printf("mtx exists\n"); |
| | | if (TryLock()) { |
| | | auto op = [&]() { |
| | | if (TryLock()) { |
| | | Unlock(); |
| | | } |
| | | }; |
| | | op(); |
| | | std::thread t(op); |
| | | t.join(); |
| | | // Unlock(); |
| | | } else { |
| | | // mtx->unlock(); |
| | | } |
| | | } else { |
| | | printf("mtx not exists\n"); |
| | | } |
| | | } |
| | | |
| | | BOOST_AUTO_TEST_CASE(ApiTest) |
| | | { |
| | | auto max_time = std::chrono::steady_clock::time_point::max(); |
| | |
| | | |
| | | printf("maxsec: %ld\n", CountSeconds(max_time)); |
| | | |
| | | // BHCleanup(); |
| | | // return; |
| | | bool reg = false; |
| | | for (int i = 0; i < 3 && !reg; ++i) { |
| | | ProcInfo proc; |
| | |
| | | void *reply = 0; |
| | | int reply_len = 0; |
| | | reg = BHRegister(proc_buf.data(), proc_buf.size(), &reply, &reply_len, 2000); |
| | | printf("register %s\n", reg ? "ok" : "failed"); |
| | | if (reg) { |
| | | printf("register ok\n"); |
| | | // bool r = BHUnregister(proc_buf.data(), proc_buf.size(), &reply, &reply_len, 2000); |
| | | // printf("unregister %s\n", r ? "ok" : "failed"); |
| | | // reg = BHRegister(proc_buf.data(), proc_buf.size(), &reply, &reply_len, 2000); |
| | | // if (!reg) { |
| | | // int ec = 0; |
| | | // std::string msg; |
| | | // GetLastError(ec, msg); |
| | | // printf("reg error: %s\n", msg.c_str()); |
| | | // } |
| | | } else { |
| | | int ec = 0; |
| | | std::string msg; |
| | | GetLastError(ec, msg); |
| | | printf("register failed, %d, %s\n", ec, msg.c_str()); |
| | | } |
| | | |
| | | BHFree(reply, reply_len); |
| | | Sleep(1s); |
| | |
| | | void *reply = 0; |
| | | int reply_len = 0; |
| | | bool r = BHRegisterTopics(s.data(), s.size(), &reply, &reply_len, 1000); |
| | | BHFree(reply, reply_len); |
| | | DEFER1(BHFree(reply, reply_len)); |
| | | // printf("register topic : %s\n", r ? "ok" : "failed"); |
| | | Sleep(1s); |
| | | // Sleep(1s); |
| | | } |
| | | { |
| | | // query procs |
| | | std::string dest(BHAddress().SerializeAsString()); |
| | | MsgQueryProc query; |
| | | std::string s = query.SerializeAsString(); |
| | | void *reply = 0; |
| | | int reply_len = 0; |
| | | bool r = BHQueryProcs(dest.data(), dest.size(), s.data(), s.size(), &reply, &reply_len, 1000); |
| | | DEFER1(BHFree(reply, reply_len)); |
| | | MsgQueryProcReply result; |
| | | if (result.ParseFromArray(reply, reply_len) && IsSuccess(result.errmsg().errcode())) { |
| | | printf("query proc result: %d\n", result.proc_list().size()); |
| | | for (int i = 0; i < result.proc_list().size(); ++i) { |
| | | auto &info = result.proc_list(i); |
| | | printf("proc [%d] %s, %s, %s\n\ttopics\n", i, |
| | | (info.online() ? "online" : "offline"), |
| | | info.proc().proc_id().c_str(), info.proc().name().c_str()); |
| | | for (auto &t : info.topics().topic_list()) { |
| | | printf("\t\t %s", t.c_str()); |
| | | } |
| | | } |
| | | } else { |
| | | printf("query proc error\n"); |
| | | } |
| | | // printf("register topic : %s\n", r ? "ok" : "failed"); |
| | | // Sleep(1s); |
| | | } |
| | | |
| | | { // Subscribe |
| | |
| | | |
| | | auto SyncRequest = [&](int idx) { // SyncRequest |
| | | MsgRequestTopic req; |
| | | req.set_topic(topic_ + std::to_string(idx)); |
| | | req.set_topic(topic_ + std::to_string(0)); |
| | | req.set_data("request_data_" + std::to_string(idx)); |
| | | std::string s(req.SerializeAsString()); |
| | | // Sleep(10ms, false); |
| | |
| | | DEFER1(BHFree(msg_id, len);); |
| | | // Sleep(10ms, false); |
| | | std::string dest(BHAddress().SerializeAsString()); |
| | | |
| | | bool r = BHAsyncRequest(dest.data(), dest.size(), s.data(), s.size(), 0, 0); |
| | | if (r) { |
| | | ++Status().nrequest_; |
| | |
| | | |
| | | std::atomic<bool> run(true); |
| | | |
| | | BHStartWorker(&ServerProc, &SubRecvProc, &ClientProc); |
| | | ThreadManager threads; |
| | | |
| | | #if 0 |
| | | BHStartWorker(&ServerProc, &SubRecvProc, &ClientProc); |
| | | #else |
| | | BHStartWorker(FServerCallback(), &SubRecvProc, &ClientProc); |
| | | threads.Launch(ServerLoop, &run); |
| | | #endif |
| | | |
| | | boost::timer::auto_cpu_timer timer; |
| | | threads.Launch(hb, &run); |
| | | threads.Launch(showStatus, &run); |
| | | int ncli = 10; |
| | | const uint64_t nreq = 1000 * 100; |
| | | const int64_t nreq = 1000 * 100; |
| | | |
| | | for (int i = 0; i < 100; ++i) { |
| | | SyncRequest(i); |
| | | } |
| | | |
| | | for (int i = 0; i < ncli; ++i) { |
| | | threads.Launch(asyncRequest, nreq); |
| | | } |
| | | // for (int i = 0; i < 100; ++i) { |
| | | // SyncRequest(0); |
| | | // } |
| | | |
| | | int same = 0; |
| | | int64_t last = 0; |
| | | while (last < nreq * ncli && same < 2) { |
| | | uint64_t last = 0; |
| | | while (last < nreq * ncli && same < 3) { |
| | | Sleep(1s, false); |
| | | auto cur = Status().nreply_.load(); |
| | | if (last == cur) { |
| | | ++same; |
| | | printf("same %d\n", same); |
| | | } else { |
| | | last = cur; |
| | | same = 0; |
| | |
| | | run = false; |
| | | threads.WaitAll(); |
| | | auto &st = Status(); |
| | | Sleep(1s); |
| | | printf("nreq: %8ld, nsrv: %8ld, nreply: %8ld\n", st.nrequest_.load(), st.nserved_.load(), st.nreply_.load()); |
| | | BHCleanup(); |
| | | printf("after cleanup\n"); |