McrouterClient::McrouterClient( std::weak_ptr<McrouterInstance> rtr, mcrouter_client_callbacks_t callbacks, void* arg, size_t maxOutstanding, bool maxOutstandingError, bool sameThread) : router_(std::move(rtr)), sameThread_(sameThread), callbacks_(callbacks), arg_(arg), maxOutstanding_(maxOutstanding), maxOutstandingError_(maxOutstandingError) { static std::atomic<uint64_t> nextClientId(0ULL); clientId_ = nextClientId++; if (maxOutstanding_ != 0) { counting_sem_init(&outstandingReqsSem_, maxOutstanding_); } if (auto router = router_.lock()) { std::lock_guard<std::mutex> guard(router->nextProxyMutex_); assert(router->nextProxy_ < router->opts().num_proxies); proxy_ = router->getProxy(router->nextProxy_); router->nextProxy_ = (router->nextProxy_ + 1) % router->opts().num_proxies; } }
TEST(counting_semaphore, nonblocking) { // X producers producing Y items each // Y consumer consuming X items each // Initial value is INIT, // check that we get back the same at the end int X = 523, Y = 345, INIT = 3; counting_sem_init(&sem, INIT); std::vector<std::thread> threads; for (int i = 0; i < X; ++i) { threads.push_back(std::thread{&produce, i, Y}); } for (int i = 0; i < Y; ++i) { threads.push_back(std::thread{&consume_nonblocking, i, X}); } for (auto& t : threads) { t.join(); } EXPECT_EQ(INIT, counting_sem_value(&sem)); }