/** * @file mailbox.cpp * @brief * @date Aug 16, 2015 * @author rheijden * @copyright 2015 Dual Inventive Technology Centre B.V. * * */ #include #include #include #include #include #include #include using namespace Di; using namespace std; static Mailbox mb; TEST(Mailbox, empty) { shared_ptr a = make_shared(100); shared_ptr b = make_shared(50); EXPECT_FALSE(mb.fetch(&b, false)); EXPECT_EQ(50, *b); EXPECT_FALSE(mb.fetch(&b, true, chrono::milliseconds(50))); mb.post(a); EXPECT_TRUE(mb.fetch(&b, true)); EXPECT_EQ(100, *b); mb.reset(); } void worker(int w) { shared_ptr b; Log::debug("Worker %d waiting", w); EXPECT_TRUE(mb.fetch(&b)); Log::debug("Worker %d shutting down (b = %d)", w, b.get()); } TEST(Mailbox, workers) { shared_ptr a = make_shared(0); thread w1(worker, 1), w2(worker, 2), w3(worker, 3), w4(worker, 4), w5(worker, 5), w6(worker, 6), w7(worker, 7), w8(worker, 8), w9(worker, 9), w10(worker, 10); this_thread::sleep_for(chrono::milliseconds(1000)); for (int i = 0; i < 10; i++) { *a = i; mb.post(a); this_thread::sleep_for(chrono::milliseconds(100)); } w1.join(); w2.join(); w3.join(); w4.join(); w5.join(); w6.join(); w7.join(); w8.join(); w9.join(); w10.join(); mb.reset(); } TEST(Mailbox, postorder) { mb.reset(); shared_ptr a = make_shared(10); shared_ptr b = make_shared(10); shared_ptr c; mb.post(a); mb.postAhead(b); EXPECT_TRUE(mb.fetch(&c, false)); EXPECT_EQ(*b, *c); EXPECT_TRUE(mb.fetch(&c, false)); EXPECT_EQ(*a, *c); EXPECT_FALSE(mb.fetch(&c, false)); mb.post(b); mb.post(a); EXPECT_TRUE(mb.fetch(&c, true, chrono::milliseconds(100))); EXPECT_EQ(*b, *c); EXPECT_TRUE(mb.fetch(&c, true, chrono::milliseconds(100))); EXPECT_EQ(*a, *c); EXPECT_FALSE(mb.fetch(&c, true, chrono::milliseconds(10))); } class Mailbox_test : public Mailbox { public: void setLock(void) { Log::debug("Locking the mutex"); _lock.lock(); } void unsetLock(void) { Log::debug("Unlocking the mutex"); _lock.unlock(); } }; static Mailbox_test mt; void poster(int w) { uint64_t t1, t2; Log::debug("Poster %d about to post", w); t1 = Time::getNow(); mt.post(nullptr); t2 = Time::getNow(); Log::debug("Poster %d shutting down (t1 = %lu, t2 = %lu)", w, t1, t2); ASSERT_GE((t2 - t1), 400UL); } TEST(Mailbox, post_lock) { shared_ptr b; mt.setLock(); thread w1(poster, 1); this_thread::sleep_for(chrono::milliseconds(500)); mt.unsetLock(); w1.join(); mt.reset(); } void aheadPoster(int w) { uint64_t t1, t2; Log::debug("AheadPoster %d about to post", w); t1 = Time::getNow(); mt.postAhead(nullptr); t2 = Time::getNow(); Log::debug("AheadPoster %d shutting down (t1 = %lu, t2 = %lu)", w, t1, t2); ASSERT_GE((t2 - t1), 400UL); } TEST(Mailbox, postahead_lock) { shared_ptr b; mt.setLock(); thread w1(aheadPoster, 1); this_thread::sleep_for(chrono::milliseconds(500)); mt.unsetLock(); w1.join(); mt.reset(); } void resetter(int w) { uint64_t t1, t2; Log::debug("Resetter %d about to post", w); t1 = Time::getNow(); mt.reset(); t2 = Time::getNow(); Log::debug("Resetter %d shutting down (t1 = %lu, t2 = %lu)", w, t1, t2); ASSERT_GE((t2 - t1), 400UL); } TEST(Mailbox, reset_lock) { shared_ptr b; mt.setLock(); thread w1(resetter, 1); this_thread::sleep_for(chrono::milliseconds(500)); mt.unsetLock(); w1.join(); mt.reset(); }