summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel/parallel.hpp
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-28 02:50:02 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-28 02:50:02 +0000
commit29edc4e6fb2c8fb3a93aac36d9666efd21b92bd0 (patch)
tree2b1998d904a16cdce69f69041c89cc56d474e69e /sca-cpp/trunk/kernel/parallel.hpp
parentd93ec216d63aed8ff2f08b4cba7de965dc14639c (diff)
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
Diffstat (limited to 'sca-cpp/trunk/kernel/parallel.hpp')
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp137
1 files changed, 137 insertions, 0 deletions
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<typename T> class perthread_ptr {
+public:
+ perthread_ptr() : key(createkey()), owner(true), cl(lambda<gc_ptr<T>()>()), managed(false) {
+ }
+
+ perthread_ptr(const lambda<gc_ptr<T>()>& 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<T>& v) {
+ set(v);
+ return *this;
+ }
+
+ const perthread_ptr& operator=(T* v) {
+ set(v);
+ return *this;
+ }
+
+ const bool operator==(const gc_ptr<T>& r) const throw() {
+ return get() == r;
+ }
+
+ const bool operator==(T* p) const throw() {
+ return get() == p;
+ }
+
+ const bool operator!=(const gc_ptr<T>& 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<T>() 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<T>& v) {
+ pthread_setspecific(key, (T*)v);
+ return true;
+ }
+
+ gc_ptr<T> get() const {
+ const gc_ptr<T> v = static_cast<T*>(pthread_getspecific(key));
+ if (v != NULL || !managed)
+ return v;
+ const gc_ptr<T> 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<T>& v) {
+ val = v;
+ return true;
+ }
+
+ gc_ptr<T> 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<T> val;
+#endif
+
+ bool owner;
+ lambda<const gc_ptr<T>()> cl;
+ bool managed;
+};
+
}
#endif /* tuscany_parallel_hpp */