diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-28 02:50:02 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-28 02:50:02 +0000 |
commit | 29edc4e6fb2c8fb3a93aac36d9666efd21b92bd0 (patch) | |
tree | 2b1998d904a16cdce69f69041c89cc56d474e69e /sca-cpp | |
parent | d93ec216d63aed8ff2f08b4cba7de965dc14639c (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.cpp | 15 | ||||
-rw-r--r-- | sca-cpp/trunk/components/http/httpget.cpp | 17 | ||||
-rw-r--r-- | sca-cpp/trunk/components/http/httppatch.cpp | 16 | ||||
-rw-r--r-- | sca-cpp/trunk/components/http/httppost.cpp | 16 | ||||
-rw-r--r-- | sca-cpp/trunk/components/http/httpput.cpp | 16 | ||||
-rw-r--r-- | sca-cpp/trunk/components/sqldb/sqldb.cpp | 32 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/gc.hpp | 35 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/parallel-test.cpp | 24 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/parallel.hpp | 137 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/string-test.cpp | 2 | ||||
-rwxr-xr-x | sca-cpp/trunk/macos/macos-install | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/js/eval.hpp | 6 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/mod-oauth1.cpp | 23 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/oauth/mod-oauth2.cpp | 27 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/scheme/primitive.hpp | 11 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-eval.hpp | 5 |
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: |