summaryrefslogtreecommitdiffstats
path: root/sca-cpp
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
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')
-rw-r--r--sca-cpp/trunk/components/http/httpdelete.cpp15
-rw-r--r--sca-cpp/trunk/components/http/httpget.cpp17
-rw-r--r--sca-cpp/trunk/components/http/httppatch.cpp16
-rw-r--r--sca-cpp/trunk/components/http/httppost.cpp16
-rw-r--r--sca-cpp/trunk/components/http/httpput.cpp16
-rw-r--r--sca-cpp/trunk/components/sqldb/sqldb.cpp32
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp35
-rw-r--r--sca-cpp/trunk/kernel/parallel-test.cpp24
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp137
-rw-r--r--sca-cpp/trunk/kernel/string-test.cpp2
-rwxr-xr-xsca-cpp/trunk/macos/macos-install5
-rw-r--r--sca-cpp/trunk/modules/js/eval.hpp6
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp23
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth2.cpp27
-rw-r--r--sca-cpp/trunk/modules/scheme/primitive.hpp11
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp5
16 files changed, 337 insertions, 50 deletions
diff --git a/sca-cpp/trunk/components/http/httpdelete.cpp b/sca-cpp/trunk/components/http/httpdelete.cpp
index 5386ba588f..5f3f8ead11 100644
--- a/sca-cpp/trunk/components/http/httpdelete.cpp
+++ b/sca-cpp/trunk/components/http/httpdelete.cpp
@@ -48,28 +48,35 @@ const failable<value> get(const lambda<value(const list<value>&)> url, http::CUR
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, http::CURLSession& ch) : url(url), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)> url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
}
const value operator()(const list<value>& params) const {
debug(params, "httpdelete::applyhttp::params");
const value func(car(params));
if (func == "get")
- return get(url, ch);
+ return get(url, *ch);
return tuscany::mkfailure<tuscany::value>();
}
private:
const lambda<value(const list<value>&)> url;
- http::CURLSession& ch;
+ perthread_ptr<http::CURLSession> ch;
};
/**
+ * Create a new CURL session.
+ */
+const gc_ptr<http::CURLSession> newsession() {
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+}
+
+/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", ""));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httpget.cpp b/sca-cpp/trunk/components/http/httpget.cpp
index ac7a99775b..fc89784749 100644
--- a/sca-cpp/trunk/components/http/httpget.cpp
+++ b/sca-cpp/trunk/components/http/httpget.cpp
@@ -28,6 +28,7 @@
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../../modules/http/http.hpp"
namespace tuscany {
@@ -48,28 +49,36 @@ const failable<value> get(const lambda<value(const list<value>&)> url, http::CUR
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, http::CURLSession& ch) : url(url), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)> url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
}
const value operator()(const list<value>& params) const {
debug(params, "httpget::applyhttp::params");
const value func(car(params));
if (func == "get")
- return get(url, ch);
+ return get(url, *ch);
return tuscany::mkfailure<tuscany::value>();
}
private:
const lambda<value(const list<value>&)> url;
- http::CURLSession& ch;
+ perthread_ptr<http::CURLSession> ch;
};
+
+/**
+ * Create a new CURL session.
+ */
+const gc_ptr<http::CURLSession> newsession() {
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+}
+
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", ""));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httppatch.cpp b/sca-cpp/trunk/components/http/httppatch.cpp
index 4debca045e..ef72537185 100644
--- a/sca-cpp/trunk/components/http/httppatch.cpp
+++ b/sca-cpp/trunk/components/http/httppatch.cpp
@@ -28,6 +28,7 @@
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../../modules/http/http.hpp"
namespace tuscany {
@@ -50,29 +51,36 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
debug(params, "httppatch::applyhttp::params");
const value func(car(params));
if (func == "get")
- return get(url, val, ch);
+ return get(url, val, *ch);
return tuscany::mkfailure<tuscany::value>();
}
private:
const lambda<value(const list<value>&)> url;
const lambda<value(const list<value>&)> val;
- http::CURLSession& ch;
+ perthread_ptr<http::CURLSession> ch;
};
/**
+ * Create a new CURL session.
+ */
+const gc_ptr<http::CURLSession> newsession() {
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+}
+
+/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", ""));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httppost.cpp b/sca-cpp/trunk/components/http/httppost.cpp
index 9784c4513c..0879ad2e59 100644
--- a/sca-cpp/trunk/components/http/httppost.cpp
+++ b/sca-cpp/trunk/components/http/httppost.cpp
@@ -28,6 +28,7 @@
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../../modules/http/http.hpp"
namespace tuscany {
@@ -50,29 +51,36 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
debug(params, "httppost::applyhttp::params");
const value func(car(params));
if (func == "get")
- return get(url, val, ch);
+ return get(url, val, *ch);
return tuscany::mkfailure<tuscany::value>();
}
private:
const lambda<value(const list<value>&)> url;
const lambda<value(const list<value>&)> val;
- http::CURLSession& ch;
+ perthread_ptr<http::CURLSession> ch;
};
/**
+ * Create a new CURL session.
+ */
+const gc_ptr<http::CURLSession> newsession() {
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+}
+
+/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", ""));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httpput.cpp b/sca-cpp/trunk/components/http/httpput.cpp
index 4ec63dabce..1eef0bef48 100644
--- a/sca-cpp/trunk/components/http/httpput.cpp
+++ b/sca-cpp/trunk/components/http/httpput.cpp
@@ -28,6 +28,7 @@
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../../modules/http/http.hpp"
namespace tuscany {
@@ -50,29 +51,36 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
debug(params, "httpput::applyhttp::params");
const value func(car(params));
if (func == "get")
- return get(url, val, ch);
+ return get(url, val, *ch);
return tuscany::mkfailure<tuscany::value>();
}
private:
const lambda<value(const list<value>&)> url;
const lambda<value(const list<value>&)> val;
- http::CURLSession& ch;
+ perthread_ptr<http::CURLSession> ch;
};
/**
+ * Create a new CURL session.
+ */
+const gc_ptr<http::CURLSession> newsession() {
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+}
+
+/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", ""));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/sqldb/sqldb.cpp b/sca-cpp/trunk/components/sqldb/sqldb.cpp
index 0524b00bd2..fa82c0ee9f 100644
--- a/sca-cpp/trunk/components/sqldb/sqldb.cpp
+++ b/sca-cpp/trunk/components/sqldb/sqldb.cpp
@@ -28,6 +28,7 @@
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "pgsql.hpp"
namespace tuscany {
@@ -76,24 +77,41 @@ const failable<value> del(const list<value>& params, pgsql::PGSql& pg) {
*/
class applySqldb {
public:
- applySqldb(pgsql::PGSql& pg) : pg(pg) {
+ applySqldb(const perthread_ptr<pgsql::PGSql>& pg) : pg(pg) {
}
const value operator()(const list<value>& params) const {
const value func(car(params));
if (func == "get")
- return get(cdr(params), pg);
+ return get(cdr(params), *pg);
if (func == "post")
- return post(cdr(params), pg);
+ return post(cdr(params), *pg);
if (func == "put")
- return put(cdr(params), pg);
+ return put(cdr(params), *pg);
if (func == "delete")
- return del(cdr(params), pg);
+ return del(cdr(params), *pg);
return tuscany::mkfailure<tuscany::value>();
}
private:
- pgsql::PGSql& pg;
+ const perthread_ptr<pgsql::PGSql> pg;
+};
+
+/**
+ * Lambda function that creates a new database connection.
+ */
+class newPGSql {
+public:
+ newPGSql(const string& conninfo, const string& table) : conninfo(conninfo), table(table) {
+ }
+
+ const gc_ptr<pgsql::PGSql> operator()() const {
+ return new (gc_new<pgsql::PGSql>()) pgsql::PGSql(conninfo, table);
+ }
+
+private:
+ const string conninfo;
+ const string table;
};
/**
@@ -103,7 +121,7 @@ const failable<value> start(unused const list<value>& params) {
// Connect to the configured database and table
const value conninfo = ((lambda<value(list<value>)>)car(params))(list<value>());
const value table = ((lambda<value(list<value>)>)cadr(params))(list<value>());
- pgsql::PGSql& pg = *(new (gc_new<pgsql::PGSql>()) pgsql::PGSql(conninfo, table));
+ const perthread_ptr<pgsql::PGSql> pg(lambda<gc_ptr<pgsql::PGSql>()>(newPGSql(conninfo, table)));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applySqldb(pg)));
diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp
index 2a8303f638..30cc637388 100644
--- a/sca-cpp/trunk/kernel/gc.hpp
+++ b/sca-cpp/trunk/kernel/gc.hpp
@@ -33,6 +33,9 @@
#include <assert.h>
#include <new>
#include "config.hpp"
+#ifdef WANT_THREADS
+#include <pthread.h>
+#endif
namespace tuscany
{
@@ -81,10 +84,18 @@ public:
return ptr == r.ptr;
}
+ const bool operator==(T* p) const throw() {
+ return ptr == 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 *ptr;
}
@@ -168,9 +179,29 @@ public:
* Maintain a stack of memory pools.
*/
#ifdef WANT_THREADS
-__thread
-#endif
+
+class gc_pool_stack_t {
+public:
+ gc_pool_stack_t() {
+ pthread_key_create(&key, NULL);
+ }
+
+ operator apr_pool_t*() const {
+ return static_cast<apr_pool_t*>(pthread_getspecific(key));
+ }
+
+ const gc_pool_stack_t& operator=(apr_pool_t* p) {
+ pthread_setspecific(key, p);
+ return *this;
+ }
+
+private:
+ pthread_key_t key;
+} gc_pool_stack;
+
+#else
apr_pool_t* gc_pool_stack = NULL;
+#endif
/**
* Return the current memory pool.
diff --git a/sca-cpp/trunk/kernel/parallel-test.cpp b/sca-cpp/trunk/kernel/parallel-test.cpp
index ab832f1472..f883d19f69 100644
--- a/sca-cpp/trunk/kernel/parallel-test.cpp
+++ b/sca-cpp/trunk/kernel/parallel-test.cpp
@@ -71,13 +71,18 @@ struct mutexPerf {
}
};
-__thread int tlsi = 0;
+const gc_ptr<int> tlsic() {
+ gc_ptr<int> i = new (gc_new<int>()) int();
+ *i = 0;
+ return i;
+}
+const perthread_ptr<int> tlsi(tlsic);
struct tlsPerf {
tlsPerf() {
}
const bool operator()() const {
- tlsi = tlsi + 1;
+ *tlsi = *tlsi + 1;
return true;
}
};
@@ -105,7 +110,7 @@ bool testAtomicPerf() {
{
const lambda<bool()> l = tlsPerf();
cout << "Thread local inc test " << time(l, 1000, count) << " ms" << endl;
- assert(tlsi == count + 1000);
+ assert(*tlsi == count + 1000);
}
return true;
}
@@ -131,18 +136,23 @@ bool checkSquareResults(const list<future<int> > r, int i) {
return true;
}
-__thread long int tlsv = 0;
+const gc_ptr<long int> tlsvc() {
+ gc_ptr<long int> i = new (gc_new<long int>()) long int();
+ *i = 0l;
+ return i;
+}
+const perthread_ptr<long int> tlsv(tlsvc);
const long int tlsset(gc_ptr<wqueue<bool>> wq, gc_ptr<wqueue<bool>> xq) {
- const long int v = tlsv;
- tlsv = threadId();
+ const long int v = *tlsv;
+ *tlsv = threadId();
enqueue(*xq, true);
dequeue(*wq);
return v;
}
const bool tlscheck(gc_ptr<wqueue<bool>> wq, gc_ptr<wqueue<bool>> xq) {
- const bool r = tlsv == threadId();
+ const bool r = *tlsv == threadId();
enqueue(*xq, true);
dequeue(*wq);
return r;
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 */
diff --git a/sca-cpp/trunk/kernel/string-test.cpp b/sca-cpp/trunk/kernel/string-test.cpp
index 5919eed3de..f2f21f6ea6 100644
--- a/sca-cpp/trunk/kernel/string-test.cpp
+++ b/sca-cpp/trunk/kernel/string-test.cpp
@@ -80,6 +80,8 @@ bool testString() {
assert(find("abcd", "cd") == 2);
assert(find("abcd", "xy") == length("abcd"));
+ assert(find_first_of("abcd", "cd") == 2);
+ assert(find_first_of("abcd", "xy") == length("abcd"));
assert(substr("abcdef", 4) == "ef");
assert(substr("abcdef", 4, 2) == "ef");
assert(substr("abcdef", 4, 3) == "ef");
diff --git a/sca-cpp/trunk/macos/macos-install b/sca-cpp/trunk/macos/macos-install
index 87b99b051f..6d7b90cd28 100755
--- a/sca-cpp/trunk/macos/macos-install
+++ b/sca-cpp/trunk/macos/macos-install
@@ -156,6 +156,11 @@ cd nspr-4.8.8/mozilla/nsprpub
./configure --prefix=$build/nspr-4.8.8-bin --enable-64bit
make
make install
+install_name_tool -id $build/nspr-4.8.8-bin/lib/libnspr4.dylib $build/nspr-4.8.8-bin/lib/libnspr4.dylib
+install_name_tool -id $build/nspr-4.8.8-bin/lib/libplc4.dylib $build/nspr-4.8.8-bin/lib/libplc4.dylib
+install_name_tool -id $build/nspr-4.8.8-bin/lib/libplds4.dylib $build/nspr-4.8.8-bin/lib/libplds4.dylib
+install_name_tool -change @executable_path/libnspr4.dylib $build/nspr-4.8.8-bin/lib/libnspr4.dylib $build/nspr-4.8.8-bin/lib/libplc4.dylib
+install_name_tool -change @executable_path/libnspr4.dylib $build/nspr-4.8.8-bin/lib/libnspr4.dylib $build/nspr-4.8.8-bin/lib/libplds4.dylib
if [ "$?" != "0" ]; then
exit $?
fi
diff --git a/sca-cpp/trunk/modules/js/eval.hpp b/sca-cpp/trunk/modules/js/eval.hpp
index f18c3e41c9..69863c9831 100644
--- a/sca-cpp/trunk/modules/js/eval.hpp
+++ b/sca-cpp/trunk/modules/js/eval.hpp
@@ -43,6 +43,7 @@
#include "value.hpp"
#include "element.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
namespace tuscany {
namespace js {
@@ -106,9 +107,10 @@ JSClass jsGlobalClass = { "global", JSCLASS_GLOBAL_FLAGS,
* Represents a JavaScript context. Maintains one context per thread.
*/
#ifdef WANT_THREADS
-__thread
-#endif
+perthread_ptr<JSContext> jsContext;
+#else
::JSContext* jsContext = NULL;
+#endif
class JSContext {
public:
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
index 252d5c5ee0..ca7f562b60 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
@@ -36,6 +36,7 @@ extern "C" {
#include "tree.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../json/json.hpp"
#include "../http/httpd.hpp"
#include "../http/http.hpp"
@@ -65,7 +66,7 @@ public:
list<list<value> > appkeys;
list<string> mcaddrs;
memcache::MemCached mc;
- http::CURLSession cs;
+ perthread_ptr<http::CURLSession> cs;
};
/**
@@ -476,6 +477,24 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
}
/**
+ * Lambda function that creates a new CURL session.
+ */
+class newsession {
+public:
+ newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) {
+ }
+
+ const gc_ptr<http::CURLSession> operator()() const {
+ return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "");
+ }
+
+private:
+ const string ca;
+ const string cert;
+ const string key;
+};
+
+/**
* Child process initialization.
*/
void childInit(apr_pool_t* p, server_rec* s) {
@@ -494,7 +513,7 @@ void childInit(apr_pool_t* p, server_rec* s) {
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs));
// Setup a CURL session
- sc.cs = *(new (gc_new<http::CURLSession>()) http::CURLSession(sc.ca, sc.cert, sc.key, ""));
+ sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key)));
// Merge the updated configuration into the virtual hosts
postConfigMerge(sc, s->next);
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
index 2e4b2e5b80..41d722f1e2 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
@@ -31,6 +31,7 @@
#include "tree.hpp"
#include "value.hpp"
#include "monad.hpp"
+#include "parallel.hpp"
#include "../http/httpd.hpp"
#include "../http/http.hpp"
#include "../http/openauth.hpp"
@@ -59,7 +60,7 @@ public:
list<list<value> > appkeys;
list<string> mcaddrs;
memcache::MemCached mc;
- http::CURLSession cs;
+ perthread_ptr<http::CURLSession> cs;
};
/**
@@ -199,7 +200,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r,
const list<list<value> > targs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code);
const string turi = httpd::unescape(cadr(tok)) + string("?") + http::queryString(targs);
debug(turi, "modoauth2::access_token::tokenuri");
- const failable<value> tr = http::get(turi, sc.cs);
+ const failable<value> tr = http::get(turi, *(sc.cs));
if (!hasContent(tr))
return mkfailure<int>(reason(tr));
debug(tr, "modoauth2::access_token::response");
@@ -213,7 +214,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r,
const list<list<value> > iargs = mklist<list<value> >(tv);
const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs);
debug(iuri, "modoauth2::access_token::infouri");
- const failable<value> profres = http::get(iuri, sc.cs);
+ const failable<value> profres = http::get(iuri, *(sc.cs));
if (!hasContent(profres))
return mkfailure<int>("Couldn't retrieve user info");
debug(content(profres), "modoauth2::access_token::info");
@@ -328,6 +329,24 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
}
/**
+ * Lambda function that creates a new CURL session.
+ */
+class newsession {
+public:
+ newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) {
+ }
+
+ const gc_ptr<http::CURLSession> operator()() const {
+ return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "");
+ }
+
+private:
+ const string ca;
+ const string cert;
+ const string key;
+};
+
+/**
* Child process initialization.
*/
void childInit(apr_pool_t* p, server_rec* s) {
@@ -346,7 +365,7 @@ void childInit(apr_pool_t* p, server_rec* s) {
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs));
// Setup a CURL session
- sc.cs = *(new (gc_new<http::CURLSession>()) http::CURLSession(sc.ca, sc.cert, sc.key, ""));
+ sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key)));
// Merge the updated configuration into the virtual hosts
postConfigMerge(sc, s->next);
diff --git a/sca-cpp/trunk/modules/scheme/primitive.hpp b/sca-cpp/trunk/modules/scheme/primitive.hpp
index 899d6f83da..59aee12073 100644
--- a/sca-cpp/trunk/modules/scheme/primitive.hpp
+++ b/sca-cpp/trunk/modules/scheme/primitive.hpp
@@ -30,6 +30,7 @@
#include "function.hpp"
#include "list.hpp"
#include "value.hpp"
+#include "parallel.hpp"
namespace tuscany {
namespace scheme {
@@ -39,14 +40,16 @@ const value quoteSymbol("'");
const value lambdaSymbol("lambda");
#ifdef WANT_THREADS
-__thread
-#endif
+perthread_ptr<ostream> displayOutStream;
+#else
ostream* displayOutStream = NULL;
+#endif
#ifdef WANT_THREADS
-__thread
-#endif
+perthread_ptr<ostream> logOutStream;
+#else
ostream* logOutStream = NULL;
+#endif
const bool setupDisplay(ostream& out) {
displayOutStream = &out;
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index b9b11e06dc..34cdfdbb29 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -100,9 +100,10 @@ const failable<value> failableResult(const list<value>& v) {
* Store current HTTP request for access from property and proxy lambda functions.
*/
#ifdef WANT_THREADS
-__thread
-#endif
+perthread_ptr<request_rec> currentRequest;
+#else
request_rec* currentRequest = NULL;
+#endif
class ScopedRequest {
public: