TEST(TestMultipleSharedSection, General) { CSharedSection sec; CEvent event; std::atomic<long> mutex(0L); locker<CSharedLock> l1(sec,&mutex, &event); { CSharedLock lock(sec); thread waitThread1(l1); EXPECT_TRUE(waitForThread(mutex,1,10000)); SleepMillis(10); EXPECT_TRUE(l1.haslock); event.Set(); EXPECT_TRUE(waitThread1.timed_join(MILLIS(10000))); } locker<CSharedLock> l2(sec,&mutex,&event); locker<CSharedLock> l3(sec,&mutex,&event); locker<CSharedLock> l4(sec,&mutex,&event); locker<CSharedLock> l5(sec,&mutex,&event); { CExclusiveLock lock(sec); thread waitThread1(l2); thread waitThread2(l3); thread waitThread3(l4); thread waitThread4(l5); EXPECT_TRUE(waitForThread(mutex,4,10000)); SleepMillis(10); EXPECT_TRUE(!l2.haslock); EXPECT_TRUE(!l3.haslock); EXPECT_TRUE(!l4.haslock); EXPECT_TRUE(!l5.haslock); lock.Leave(); EXPECT_TRUE(waitForWaiters(event,4,10000)); EXPECT_TRUE(l2.haslock); EXPECT_TRUE(l3.haslock); EXPECT_TRUE(l4.haslock); EXPECT_TRUE(l5.haslock); event.Set(); EXPECT_TRUE(waitThread1.timed_join(MILLIS(10000))); EXPECT_TRUE(waitThread2.timed_join(MILLIS(10000))); EXPECT_TRUE(waitThread3.timed_join(MILLIS(10000))); EXPECT_TRUE(waitThread4.timed_join(MILLIS(10000))); } }
inline void operator()() { staticThinggy = new Thinggy; staticThreadLocal.set(staticThinggy); waiting = true; gate.Set(); waiter.Wait(); waiting = false; threadLocalHadValue = staticThreadLocal.get() != NULL; gate.Set(); }
TEST(TestSharedSection, TwoCase) { CSharedSection sec; CEvent event; std::atomic<long> mutex(0L); locker<CSharedLock> l1(sec,&mutex,&event); { CSharedLock lock(sec); thread waitThread1(l1); EXPECT_TRUE(waitForWaiters(event,1,10000)); EXPECT_TRUE(l1.haslock); event.Set(); EXPECT_TRUE(waitThread1.timed_join(MILLIS(10000))); } locker<CSharedLock> l2(sec,&mutex,&event); { CExclusiveLock lock(sec); // get exclusive lock thread waitThread2(l2); // thread should block EXPECT_TRUE(waitForThread(mutex,1,10000)); SleepMillis(10); EXPECT_TRUE(!l2.haslock); lock.Leave(); EXPECT_TRUE(waitForWaiters(event,1,10000)); SleepMillis(10); EXPECT_TRUE(l2.haslock); event.Set(); EXPECT_TRUE(waitThread2.timed_join(MILLIS(10000))); } }
virtual void OnNodeRepeat(CAcmUdp* pUdp) { uint32 nState = GetState(); uint32 nDomain = pUdp->GetDomain(); uint32 nNode = pUdp->GetNode(); if(nState < FOCP_SERVICE_STARTED) { m_bNodeRepeat = true; m_oEvent.Set(); FocpLog(FOCP_LOG_ERROR, ("The current node(nDomain=%u, nNode=%u) is repeated with the network environment", nDomain, nNode)); } else FocpLog(FOCP_LOG_ERROR, ("The visitor node(nDomain=%u, nNode=%u) is repeated with the current node", nDomain, nNode)); }
TEST(TestThreadLocal, Simple) { GlobalThreadLocal runnable; thread t(runnable); gate.Wait(); EXPECT_TRUE(runnable.waiting); EXPECT_TRUE(staticThinggy != NULL); EXPECT_TRUE(staticThreadLocal.get() == NULL); waiter.Set(); gate.Wait(); EXPECT_TRUE(runnable.threadLocalHadValue); EXPECT_TRUE(!destructorCalled); delete staticThinggy; EXPECT_TRUE(destructorCalled); cleanup(); }
unsigned __stdcall ThreadFunction( void *pParam ) { IClient *pClient = ( IClient * )pParam; ASSERT( pClient ); while ( !m_theQuitThreadEvent.Wait( 0 ) ) { size_t dataLength = 0; const void *pData = pClient->GetPackFromServer( dataLength ); if ( !pData || 0 == dataLength ) { Sleep( 1 ); continue; } EXTEND_HEADER* pHeader = (EXTEND_HEADER*)pData; if (pHeader->ProtocolFamily == pf_relay) { if (pHeader->ProtocolID == relay_c2c_data) { RELAY_DATA* pRelayCmd = (RELAY_DATA*)pData; in_addr ia; ia.s_addr = pRelayCmd->nFromIP; cout << "relaydata: " << inet_ntoa(ia) << '(' << pRelayCmd->nFromRelayID << ')' << " -- recv size: " << dataLength << endl; } if (pHeader->ProtocolID == relay_s2c_loseway) { RELAY_DATA* pRelayCmd = (RELAY_DATA*)pData; in_addr ia; ia.s_addr = pRelayCmd->nFromIP; cout << "loseway: " << inet_ntoa(ia) << '(' << pRelayCmd->nFromRelayID << ')' << " -- recv size: " << dataLength << endl; } } } cout << "The read thread was killed safely!" << endl; m_theAfirmThreadQuitEvent.Set(); return 0; }
void __stdcall ClientEventNotify( LPVOID lpParam, const unsigned long &ulnEventType ) { switch( ulnEventType ) { case enumServerConnectCreate: cout << "Server connection was created !" << endl; break; case enumServerConnectClose: cout << "Server connection was destroy !" << endl; m_theQuitThreadEvent.Set(); break; } }
TEST(TestSharedSection, GetSharedLockWhileTryingExclusiveLock) { std::atomic<long> mutex(0L); CEvent event; CSharedSection sec; CSharedLock l1(sec); // get a shared lock locker<CExclusiveLock> l2(sec,&mutex); thread waitThread1(l2); // try to get an exclusive lock EXPECT_TRUE(waitForThread(mutex,1,10000)); SleepMillis(10); // still need to give it a chance to move ahead EXPECT_TRUE(!l2.haslock); // this thread is waiting ... EXPECT_TRUE(!l2.obtainedlock); // this thread is waiting ... // now try and get a SharedLock locker<CSharedLock> l3(sec,&mutex,&event); thread waitThread3(l3); // try to get a shared lock EXPECT_TRUE(waitForThread(mutex,2,10000)); SleepMillis(10); EXPECT_TRUE(l3.haslock); event.Set(); EXPECT_TRUE(waitThread3.timed_join(MILLIS(10000))); // l3 should have released. EXPECT_TRUE(!l3.haslock); // but the exclusive lock should still not have happened EXPECT_TRUE(!l2.haslock); // this thread is waiting ... EXPECT_TRUE(!l2.obtainedlock); // this thread is waiting ... // let it go l1.Leave(); // the last shared lock leaves. EXPECT_TRUE(waitThread1.timed_join(MILLIS(10000))); EXPECT_TRUE(l2.obtainedlock); // the exclusive lock was captured EXPECT_TRUE(!l2.haslock); // ... but it doesn't have it anymore }
TEST(TestThreadLocal, HeapDestroyed) { { HeapThreadLocal runnable; thread t(runnable); gate.Wait(); EXPECT_TRUE(runnable.waiting); EXPECT_TRUE(staticThinggy != NULL); EXPECT_TRUE(runnable.threadLocal.get() == NULL); waiter.Set(); gate.Wait(); EXPECT_TRUE(runnable.threadLocalHadValue); EXPECT_TRUE(!destructorCalled); } // runnable goes out of scope // even though the threadlocal is gone ... EXPECT_TRUE(!destructorCalled); delete staticThinggy; EXPECT_TRUE(destructorCalled); cleanup(); }