summaryrefslogtreecommitdiff
path: root/cpp/test/Ice/gc/Client.cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-10-20 23:18:23 +0000
committerMichi Henning <michi@zeroc.com>2003-10-20 23:18:23 +0000
commit8941640745d51e543fadc0524368d5f861691152 (patch)
tree384020f2b665d7f1a1c20b5ea435e0bf74faf476 /cpp/test/Ice/gc/Client.cpp
parentmerging changes from garbage collector (diff)
downloadice-8941640745d51e543fadc0524368d5f861691152.tar.bz2
ice-8941640745d51e543fadc0524368d5f861691152.tar.xz
ice-8941640745d51e543fadc0524368d5f861691152.zip
merging changes for garbage collector
Diffstat (limited to 'cpp/test/Ice/gc/Client.cpp')
-rw-r--r--cpp/test/Ice/gc/Client.cpp426
1 files changed, 426 insertions, 0 deletions
diff --git a/cpp/test/Ice/gc/Client.cpp b/cpp/test/Ice/gc/Client.cpp
new file mode 100644
index 00000000000..80edbe65aac
--- /dev/null
+++ b/cpp/test/Ice/gc/Client.cpp
@@ -0,0 +1,426 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <IceUtil/Thread.h>
+#include <Ice/Ice.h>
+#include <TestCommon.h>
+#include <Test.h>
+#include <fstream>
+
+using namespace std;
+
+static int num = 0;
+
+struct N : public C
+{
+ N()
+ {
+ ++num;
+ }
+
+ ~N()
+ {
+ --num;
+ }
+};
+
+typedef ::IceInternal::Handle<N> NPtr;
+
+class GarbageProducer : public ::IceUtil::Thread, public ::IceUtil::Monitor< ::IceUtil::Mutex>
+{
+public:
+
+ GarbageProducer()
+ {
+ _stop = false;
+ }
+
+ virtual void run()
+ {
+ static ::IceUtil::Time noTime = ::IceUtil::Time::microSeconds(0);
+
+ while(true)
+ {
+ {
+ ::IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+ timedWait(noTime);
+ if(_stop)
+ {
+ return;
+ }
+ }
+
+ {
+ 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* []);
+};
+
+int
+MyApplication::run(int argc, char* argv[])
+{
+ cout << "testing single instance... " << flush;
+ {
+ NPtr n = new N;
+ test(num == 1);
+ Ice::collectGarbage();
+ test(num == 1);
+ }
+ test(num == 0);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing single instance loop... " << flush;
+ {
+ NPtr n = new N;
+ n->left = n;
+ test(num == 1);
+ Ice::collectGarbage();
+ test(num == 1);
+ }
+ test(num == 1);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing single instance loop with double pointers... " << flush;
+ {
+ NPtr n = new N;
+ n->left = n;
+ n->right = n;
+ test(num == 1);
+ Ice::collectGarbage();
+ test(num == 1);
+ }
+ test(num == 1);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing double instance loop... " << flush;
+ {
+ NPtr n1 = new N;
+ NPtr n2 = new N;
+ n1->left = n2;
+ n2->left = n1;
+ test(num == 2);
+ Ice::collectGarbage();
+ test(num == 2);
+ }
+ test(num == 2);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing double instance loop 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(num == 2);
+ Ice::collectGarbage();
+ test(num == 2);
+ }
+ test(num == 2);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing double instance loop 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(num == 2);
+ Ice::collectGarbage();
+ test(num == 2);
+ }
+ test(num == 2);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing triple instance loop... " << flush;
+ {
+ NPtr n1 = new N;
+ NPtr n2 = new N;
+ NPtr n3 = new N;
+ n1->left = n2;
+ n2->left = n3;
+ n3->left = n1;
+ test(num == 3);
+ Ice::collectGarbage();
+ test(num == 3);
+ }
+ test(num == 3);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing triple instance loop 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(num == 3);
+ Ice::collectGarbage();
+ test(num == 3);
+ }
+ test(num == 3);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing triple instance loop 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(num == 3);
+ Ice::collectGarbage();
+ test(num == 3);
+ }
+ test(num == 3);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing loop 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(num == 4);
+ Ice::collectGarbage();
+ test(num == 4);
+ }
+ test(num == 4);
+ Ice::collectGarbage();
+ test(num == 2);
+ n = 0;
+ test(num == 0);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ cout << "testing loop with trailing instances and trailing loop... " << 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(num == 6);
+ Ice::collectGarbage();
+ test(num == 6);
+ }
+ test(num == 6);
+ Ice::collectGarbage();
+ test(num == 3);
+ n = 0;
+ test(num == 2);
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ 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())
+ {
+ garbageThread->randomWait();
+ Ice::collectGarbage();
+ }
+ }
+
+ garbageThread->stop();
+ Ice::collectGarbage();
+ test(num == 0);
+ cout << "ok" << endl;
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ MyApplication app;
+ return app.main(argc, argv);
+}