📄 client.cpp
字号:
// **********************************************************************//// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.//// This copy of Ice is licensed to you under the terms described in the// ICE_LICENSE file included in this distribution.//// **********************************************************************#include <IceUtil/Thread.h>#include <IceUtil/StaticMutex.h>#include <Ice/Ice.h>#include <TestCommon.h>#include <Test.h>#include <fstream>using namespace std;using namespace Test;static int num = 0;static ::IceUtil::StaticMutex numMutex = ICE_STATIC_MUTEX_INITIALIZER;static voidincNum(){ ::IceUtil::StaticMutex::Lock lock(numMutex); ++num;}static voiddecNum(){ ::IceUtil::StaticMutex::Lock lock(numMutex); --num;}static intgetNum(){ ::IceUtil::StaticMutex::Lock lock(numMutex); return num;}struct N : public C{ N() { incNum(); } ~N() { decNum(); }};typedef ::IceInternal::Handle<N> NPtr;struct N2 : public C2{ N2() { incNum(); } ~N2() { decNum(); }};typedef ::IceInternal::Handle<N2> N2Ptr;struct NN : public Node{ NN() { incNum(); } ~NN() { decNum(); }};typedef ::IceInternal::Handle<NN> NNPtr;struct NL : public Leaf{ NL() { incNum(); } ~NL() { decNum(); }};typedef ::IceInternal::Handle<NL> NLPtr;class GarbageProducer : public ::IceUtil::Thread, public ::IceUtil::Monitor< ::IceUtil::Mutex>{public: GarbageProducer() { _stop = false; } virtual void run() { ::IceUtil::ThreadControl t = getThreadControl(); while(true) { { ::IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); if(_stop) { return; } } t.yield(); { NPtr n = new N; n->left = n; } { NPtr n = new N; n->left = n; n->right = n; } { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; } { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; n1->right = n2; n2->right = n1; } { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; n1->right = n1; n2->right = n2; } { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; } { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; n1->right = n2; n2->right = n3; n3->right = n1; } { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; n1->right = n3; n2->right = n1; n3->right = n2; } { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; NPtr n4 = new N; n1->left = n2; n2->left = n1; n2->right = n3; n3->left = n4; } { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; NPtr n4 = new N; NPtr n5 = new N; NPtr n6 = new N; n1->left = n2; n2->left = n1; n2->right = n3; n3->left = n4; n4->right = n5; n5->right = n6; n6->right = n5; } } } void stop() { { ::IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); _stop = true; notify(); } getThreadControl().join(); } void randomWait() { ::IceUtil::Time waitTime = ::IceUtil::Time::milliSeconds(10 + rand() % 50); ::IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); timedWait(waitTime); }private: bool _stop;};class MyApplication : public Ice::Application{public: virtual int run(int, char* []);};intMyApplication::run(int argc, char* argv[]){ cout << "testing single instance... " << flush; { NPtr n = new N; test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 1); } test(getNum() == 0); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing single instance cycle... " << flush; { NPtr n = new N; n->left = n; test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 1); } test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing single instance cycle with double pointers... " << flush; { NPtr n = new N; n->left = n; n->right = n; test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 1); } test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing double instance cycle... " << flush; { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing double instance cycle with double pointers... " << flush; { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; n1->right = n2; n2->right = n1; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing double instance cycle with looped pointers... " << flush; { NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; n1->right = n1; n2->right = n2; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing triple instance cycle... " << flush; { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 3); } test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing triple instance cycle with double pointers... " << flush; { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; n1->right = n2; n2->right = n3; n3->right = n1; test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 3); } test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing triple instance cycle with opposing pointers... " << flush; { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; n1->left = n2; n2->left = n3; n3->left = n1; n1->right = n3; n2->right = n1; n3->right = n2; test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 3); } test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing cycle with trailing instances... " << flush; NPtr n; { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; NPtr n4 = new N; n1->left = n2; n2->left = n1; n2->right = n3; n3->left = n4; n = n3; test(getNum() == 4); Ice::collectGarbage(); test(getNum() == 4); } test(getNum() == 4); Ice::collectGarbage(); test(getNum() == 2); n = 0; test(getNum() == 0); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing cycle with trailing instances and trailing cycle... " << flush; { NPtr n1 = new N; NPtr n2 = new N; NPtr n3 = new N; NPtr n4 = new N; NPtr n5 = new N; NPtr n6 = new N; n1->left = n2; n2->left = n1; n2->right = n3; n3->left = n4; n4->right = n5; n5->right = n6; n6->right = n5; n = n4; test(getNum() == 6); Ice::collectGarbage(); test(getNum() == 6); } test(getNum() == 6); Ice::collectGarbage(); test(getNum() == 3); n = 0; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing sequence element cycle... " << flush; { CSeq cs; cs.push_back(new N); cs.push_back(new N); cs[0]->left = cs[1]; cs[1]->left = cs[0]; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing dictionary element cycle... " << flush; { CDict cd; NPtr n1 = new N; NPtr n2 = new N; n1->left = n2; n2->left = n1; cd[0] = n1; cd[1] = n2; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing sequence of struct cycle... " << flush; { SSeq ss; S s; ss.push_back(s); ss.push_back(s); ss[0].theC = new N; ss[1].theC = new N; ss[0].theC->left = ss[1].theC; ss[1].theC->left = ss[0].theC; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing sequence of struct of dictionary cycle... " << flush; { N2Ptr n2 = new N2; S2 s2; n2->theS2Seq.push_back(s2); n2->theS2Seq.push_back(s2); n2->theS2Seq[0].theC2Dict[0] = n2; n2->theS2Seq[0].theC2Dict[1] = n2; n2->theS2Seq[1].theC2Dict[0] = n2; n2->theS2Seq[1].theC2Dict[1] = n2; test(getNum() == 1); Ice::collectGarbage(); test(getNum() == 1); } Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; cout << "testing leaf nodes... " << flush; { NNPtr nn = new NN; nn->l = new NL; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } Ice::collectGarbage(); test(getNum() == 0); { NLPtr p; { NNPtr nn = new NN; p = new NL; nn->l = p; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } Ice::collectGarbage(); test(getNum() == 1); } test(getNum() == 0); { NNPtr nn = new NN; NLPtr nl = new NL; nn->l = nl; nn->n = nn; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 0); { NNPtr nn1 = new NN; NNPtr nn2 = new NN; NLPtr nl = new NL; nn1->l = nl; nn1->n = nn2; nn2->l = nl; nn2->n = nn1; test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 3); } test(getNum() == 3); Ice::collectGarbage(); test(getNum() == 0); { NLPtr nl = new NL; test(getNum() == 1); } test(getNum() == 0); Ice::collectGarbage(); test(getNum() == 0); { NNPtr nn1 = new NN; nn1->n = new NN; test(getNum() == 2); Ice::collectGarbage(); test(getNum() == 2); } test(getNum() == 0); Ice::collectGarbage(); test(getNum() == 0); cout << "ok" << endl; #if defined(_AIX) cout << "The following test may take a long time (like one full minute); please be patient." << endl;#endif cout << "testing for race conditions... " << flush; ::IceUtil::Time t = ::IceUtil::Time::now(); int seed = argc > 1 ? atoi(argv[1]) : static_cast<int>(t.toMilliSeconds()); ofstream file("seed"); file << seed << "\n"; srand(seed); typedef ::IceUtil::Handle<GarbageProducer> GarbageThreadPtr; GarbageThreadPtr garbageThread = new GarbageProducer(); garbageThread->start(); for(int i = 0; i < 50; ++i) { if(interrupted()) { break; } garbageThread->randomWait(); Ice::collectGarbage(); } garbageThread->stop(); IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1)); Ice::collectGarbage(); if(!interrupted()) { test(getNum() == 0); cout << "ok" << endl; return EXIT_SUCCESS; } else { return 130; // SIGINT + 128 }}intmain(int argc, char* argv[]){ MyApplication app; return app.main(argc, argv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -