You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2011/08/28 04:50:03 UTC

svn commit: r1162472 - in /tuscany/sca-cpp/trunk: components/http/ components/sqldb/ kernel/ macos/ modules/js/ modules/oauth/ modules/scheme/ modules/server/

Author: jsdelfino
Date: Sun Aug 28 02:50:02 2011
New Revision: 1162472

URL: http://svn.apache.org/viewvc?rev=1162472&view=rev
Log:
Implement a portable alternative to __thread and get the HTTP and SQLDB components and the Auth modules working with the HTTPD multithreaded event MPM.

Modified:
    tuscany/sca-cpp/trunk/components/http/httpdelete.cpp
    tuscany/sca-cpp/trunk/components/http/httpget.cpp
    tuscany/sca-cpp/trunk/components/http/httppatch.cpp
    tuscany/sca-cpp/trunk/components/http/httppost.cpp
    tuscany/sca-cpp/trunk/components/http/httpput.cpp
    tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp
    tuscany/sca-cpp/trunk/kernel/gc.hpp
    tuscany/sca-cpp/trunk/kernel/parallel-test.cpp
    tuscany/sca-cpp/trunk/kernel/parallel.hpp
    tuscany/sca-cpp/trunk/kernel/string-test.cpp
    tuscany/sca-cpp/trunk/macos/macos-install
    tuscany/sca-cpp/trunk/modules/js/eval.hpp
    tuscany/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
    tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
    tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp

Modified: tuscany/sca-cpp/trunk/components/http/httpdelete.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httpdelete.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httpdelete.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/httpdelete.cpp Sun Aug 28 02:50:02 2011
@@ -48,28 +48,35 @@ const failable<value> get(const lambda<v
  */
 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)));

Modified: tuscany/sca-cpp/trunk/components/http/httpget.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httpget.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httpget.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/httpget.cpp Sun Aug 28 02:50:02 2011
@@ -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<v
  */
 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)));

Modified: tuscany/sca-cpp/trunk/components/http/httppatch.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppatch.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httppatch.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/httppatch.cpp Sun Aug 28 02:50:02 2011
@@ -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<v
  */
 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)));

Modified: tuscany/sca-cpp/trunk/components/http/httppost.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppost.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httppost.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/httppost.cpp Sun Aug 28 02:50:02 2011
@@ -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<v
  */
 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)));

Modified: tuscany/sca-cpp/trunk/components/http/httpput.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httpput.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httpput.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/httpput.cpp Sun Aug 28 02:50:02 2011
@@ -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<v
  */
 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)));

Modified: tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp Sun Aug 28 02:50:02 2011
@@ -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<val
  */
 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
     // 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)));

Modified: tuscany/sca-cpp/trunk/kernel/gc.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/gc.hpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/gc.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/gc.hpp Sun Aug 28 02:50:02 2011
@@ -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.

Modified: tuscany/sca-cpp/trunk/kernel/parallel-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/parallel-test.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/parallel-test.cpp (original)
+++ tuscany/sca-cpp/trunk/kernel/parallel-test.cpp Sun Aug 28 02:50:02 2011
@@ -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<futur
     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;

Modified: tuscany/sca-cpp/trunk/kernel/parallel.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/parallel.hpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/parallel.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/parallel.hpp Sun Aug 28 02:50:02 2011
@@ -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 */

Modified: tuscany/sca-cpp/trunk/kernel/string-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/string-test.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/string-test.cpp (original)
+++ tuscany/sca-cpp/trunk/kernel/string-test.cpp Sun Aug 28 02:50:02 2011
@@ -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");

Modified: tuscany/sca-cpp/trunk/macos/macos-install
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/macos/macos-install?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/macos/macos-install (original)
+++ tuscany/sca-cpp/trunk/macos/macos-install Sun Aug 28 02:50:02 2011
@@ -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

Modified: tuscany/sca-cpp/trunk/modules/js/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/eval.hpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/js/eval.hpp Sun Aug 28 02:50:02 2011
@@ -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", JSCL
  * 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:

Modified: tuscany/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp Sun Aug 28 02:50:02 2011
@@ -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
 }
 
 /**
+ * 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
         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);

Modified: tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp Sun Aug 28 02:50:02 2011
@@ -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 l
     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 l
     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
 }
 
 /**
+ * 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
         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);

Modified: tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp Sun Aug 28 02:50:02 2011
@@ -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;

Modified: tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp?rev=1162472&r1=1162471&r2=1162472&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Sun Aug 28 02:50:02 2011
@@ -100,9 +100,10 @@ const failable<value> failableResult(con
  * 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: