From 29edc4e6fb2c8fb3a93aac36d9666efd21b92bd0 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Sun, 28 Aug 2011 02:50:02 +0000 Subject: Implement a portable alternative to __thread and get the HTTP and SQLDB components and the Auth modules working with the HTTPD multithreaded event MPM. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1162472 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/kernel/parallel.hpp | 137 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'sca-cpp/trunk/kernel/parallel.hpp') diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp index 9c75b8fb91..648cd60cfc 100644 --- a/sca-cpp/trunk/kernel/parallel.hpp +++ b/sca-cpp/trunk/kernel/parallel.hpp @@ -43,7 +43,11 @@ namespace tuscany { * Returns the current thread id. */ long int threadId() { +#ifdef IS_DARWIN + return syscall(SYS_thread_selfid); +#else return syscall(SYS_gettid); +#endif } /** @@ -315,5 +319,138 @@ const bool cancel(worker& w) { #endif +/** + * Represents a per-thread value. + */ +template class perthread_ptr { +public: + perthread_ptr() : key(createkey()), owner(true), cl(lambda()>()), managed(false) { + } + + perthread_ptr(const lambda()>& cl) : key(createkey()), owner(true), cl(cl), managed(true) { + } + + ~perthread_ptr() { + if (owner) + deletekey(key); + } + + perthread_ptr(const perthread_ptr& c) : key(c.key), owner(false), cl(c.cl), managed(c.managed) { + } + + perthread_ptr& operator=(const perthread_ptr& r) throw() { + if(this == &r) + return *this; + key = r.key; + owner = false; + cl = r.cl; + managed = r.managed; + return *this; + } + + const perthread_ptr& operator=(const gc_ptr& v) { + set(v); + return *this; + } + + const perthread_ptr& operator=(T* v) { + set(v); + return *this; + } + + const bool operator==(const gc_ptr& r) const throw() { + return get() == r; + } + + const bool operator==(T* p) const throw() { + return get() == p; + } + + const bool operator!=(const gc_ptr& r) const throw() { + return !this->operator==(r); + } + + const bool operator!=(T* p) const throw() { + return !this->operator==(p); + } + + T& operator*() const throw() { + return *get(); + } + + T* operator->() const throw() { + return get(); + } + + operator gc_ptr() const { + return get(); + } + + operator T*() const { + return get(); + } + +private: +#ifdef WANT_THREADS + pthread_key_t createkey() { + pthread_key_t k; + pthread_key_create(&k, NULL); + return k; + } + + bool deletekey(pthread_key_t k) { + pthread_key_delete(k); + return true; + } + + bool set(const gc_ptr& v) { + pthread_setspecific(key, (T*)v); + return true; + } + + gc_ptr get() const { + const gc_ptr v = static_cast(pthread_getspecific(key)); + if (v != NULL || !managed) + return v; + const gc_ptr nv = cl(); + pthread_setspecific(key, nv); + return nv; + } + +#else + int createkey() { + return 0; + } + + bool deletekey(unused int k) { + return true; + } + + bool set(const gc_ptr& v) { + val = v; + return true; + } + + gc_ptr get() const { + if (val != NULL || !managed) + return val; + val = cl(); + return val; + } + +#endif + +#ifdef WANT_THREADS + pthread_key_t key; +#else + int key; + gc_ptr val; +#endif + + bool owner; + lambda()> cl; + bool managed; +}; + } #endif /* tuscany_parallel_hpp */ -- cgit v1.2.3