aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-06-29 23:19:49 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-06-29 23:19:49 +0000
commitb3ff0809ae19826acc7b7de923c26399003aec55 (patch)
treed530fa65394caea602133078188b7a309e531dd0
parent2055160694846aa88d2012a77d85c6310f360074 (diff)
downloadpaludis-b3ff0809ae19826acc7b7de923c26399003aec55.tar.gz
paludis-b3ff0809ae19826acc7b7de923c26399003aec55.tar.xz
r3665@snowflake: ciaranm | 2007-06-30 00:18:15 +0100
More threading
-rw-r--r--paludis/util/instantiation_policy_TEST.cc76
-rw-r--r--paludis/util/thread.cc9
2 files changed, 71 insertions, 14 deletions
diff --git a/paludis/util/instantiation_policy_TEST.cc b/paludis/util/instantiation_policy_TEST.cc
index a74e67c..ff782a8 100644
--- a/paludis/util/instantiation_policy_TEST.cc
+++ b/paludis/util/instantiation_policy_TEST.cc
@@ -19,7 +19,16 @@
#include <paludis/util/instantiation_policy.hh>
#include <paludis/util/instantiation_policy-impl.hh>
+#include <paludis/util/thread.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/make_shared_ptr.hh>
+
+#include <algorithm>
+#include <vector>
+#include <functional>
#include <string>
+
#include <test/test_framework.hh>
#include <test/test_runner.hh>
@@ -33,10 +42,6 @@ using namespace paludis;
namespace
{
- /**
- * Test class for InstantiationPolicy.
- *
- */
class MyClass :
public InstantiationPolicy<MyClass, instantiation_method::SingletonTag>
{
@@ -94,14 +99,32 @@ namespace
{
}
};
+
+ class MyThreadedClass :
+ public InstantiationPolicy<MyThreadedClass, instantiation_method::SingletonTag>
+ {
+ friend class InstantiationPolicy<MyThreadedClass, instantiation_method::SingletonTag>;
+
+ private:
+ MyThreadedClass()
+ {
+ Lock l(mutex);
+ ++instances;
+ }
+
+ public:
+ std::string s;
+
+ static Mutex mutex;
+ static int instances;
+ };
+
+ int MyThreadedClass::instances = 0;
+ Mutex MyThreadedClass::mutex;
}
namespace test_cases
{
- /**
- * \test Test singleton behaviour.
- *
- */
struct SingletonPatternTest : TestCase
{
SingletonPatternTest() : TestCase("singleton test") { }
@@ -123,10 +146,39 @@ namespace test_cases
}
} test_singleton_pattern;
- /**
- * \test Test singleton behaviour.
- *
- */
+ struct SingletonThreadedTest : TestCase
+ {
+ SingletonThreadedTest() : TestCase("singleton threaded test") { }
+
+ bool repeatable() const
+ {
+ return false;
+ }
+
+ static void thread_func(void * * const p) throw ()
+ {
+ *p = MyThreadedClass::get_instance();
+ }
+
+ void run()
+ {
+ using namespace tr1::placeholders;
+ const int c = 1000;
+
+ std::vector<void *> a(c, static_cast<void *>(0));
+ TEST_CHECK_EQUAL(MyThreadedClass::instances, 0);
+ TEST_CHECK(c == std::count(a.begin(), a.end(), static_cast<void *>(0)));
+ {
+ std::vector<tr1::shared_ptr<Thread> > t(c);
+ for (int x(0) ; x < c ; ++x)
+ t[x] = make_shared_ptr(new Thread(tr1::bind(&thread_func, &a[x])));
+ }
+ TEST_CHECK_EQUAL(MyThreadedClass::instances, 1);
+ TEST_CHECK(0 == std::count(a.begin(), a.end(), static_cast<void *>(0)));
+ TEST_CHECK(c == std::count(a.begin(), a.end(), MyThreadedClass::get_instance()));
+ }
+ } test_singleton_threaded;
+
struct SingletonPatternDeleteTest : TestCase
{
SingletonPatternDeleteTest() : TestCase("singleton delete test") { }
diff --git a/paludis/util/thread.cc b/paludis/util/thread.cc
index dc896ef..9085356 100644
--- a/paludis/util/thread.cc
+++ b/paludis/util/thread.cc
@@ -17,7 +17,10 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "thread.hh"
+#include <paludis/util/thread.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <string.h>
using namespace paludis;
@@ -27,7 +30,9 @@ Thread::Thread(const tr1::function<void () throw ()> & f) :
_thread(new pthread_t),
_func(f)
{
- pthread_create(_thread, 0, &thread_func, this);
+ int err;
+ if (0 != ((err = pthread_create(_thread, 0, &thread_func, this))))
+ throw InternalError(PALUDIS_HERE, "pthread_create failed: " + stringify(strerror(err)));
}
void *