summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk')
-rw-r--r--sca-cpp/trunk/components/cache/datacache.cpp8
-rw-r--r--sca-cpp/trunk/components/cache/memcache-test.cpp2
-rw-r--r--sca-cpp/trunk/components/cache/memcache.cpp2
-rw-r--r--sca-cpp/trunk/components/cache/memcache.hpp34
-rw-r--r--sca-cpp/trunk/components/cache/memocache.cpp2
-rw-r--r--sca-cpp/trunk/components/cache/partitioner.cpp10
-rw-r--r--sca-cpp/trunk/components/chat/chat-sender.cpp4
-rw-r--r--sca-cpp/trunk/components/chat/chat-sender2.cpp4
-rw-r--r--sca-cpp/trunk/components/chat/chat-sendreceiver.cpp4
-rw-r--r--sca-cpp/trunk/components/chat/xmpp.hpp16
-rw-r--r--sca-cpp/trunk/components/constdb/constdb.cpp2
-rw-r--r--sca-cpp/trunk/components/constdb/tinycdb.hpp13
-rw-r--r--sca-cpp/trunk/components/filedb/filedb.cpp4
-rw-r--r--sca-cpp/trunk/components/filedb/filedb.hpp12
-rw-r--r--sca-cpp/trunk/components/kvdb/client-test.cpp4
-rw-r--r--sca-cpp/trunk/components/kvdb/kvdb.cpp2
-rw-r--r--sca-cpp/trunk/components/kvdb/leveldb.hpp11
-rw-r--r--sca-cpp/trunk/components/log/log.cpp4
-rw-r--r--sca-cpp/trunk/components/log/logger.cpp4
-rw-r--r--sca-cpp/trunk/components/log/scribe-cat.cpp4
-rw-r--r--sca-cpp/trunk/components/log/scribe.hpp12
-rw-r--r--sca-cpp/trunk/components/queue/qpid.hpp9
-rw-r--r--sca-cpp/trunk/components/queue/queue-listener.cpp4
-rw-r--r--sca-cpp/trunk/components/queue/queue-sender.cpp2
-rw-r--r--sca-cpp/trunk/components/sqldb/pgsql.hpp13
-rw-r--r--sca-cpp/trunk/components/sqldb/sqldb.cpp4
-rw-r--r--sca-cpp/trunk/components/webservice/axis2.hpp9
-rwxr-xr-xsca-cpp/trunk/etc/httpd-ipcrm3
-rw-r--r--sca-cpp/trunk/hosting/server/client-test.cpp39
-rw-r--r--sca-cpp/trunk/kernel/dynlib.hpp11
-rw-r--r--sca-cpp/trunk/kernel/fstream.hpp22
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp101
-rw-r--r--sca-cpp/trunk/kernel/hash-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/lambda-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/mem-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/monad.hpp128
-rw-r--r--sca-cpp/trunk/kernel/parallel-test.cpp43
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp19
-rw-r--r--sca-cpp/trunk/kernel/perf.hpp6
-rw-r--r--sca-cpp/trunk/kernel/string-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/xml-test.cpp1
-rw-r--r--sca-cpp/trunk/kernel/xml.hpp17
-rw-r--r--sca-cpp/trunk/modules/atom/atom-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/js/eval.hpp15
-rw-r--r--sca-cpp/trunk/modules/js/js-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/json/json-test.cpp38
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp75
-rw-r--r--sca-cpp/trunk/modules/python/python-test.cpp37
-rw-r--r--sca-cpp/trunk/modules/rss/rss-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/scdl/scdl-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/scheme/scheme-test.cpp1
-rw-r--r--sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp2
-rw-r--r--sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp10
54 files changed, 601 insertions, 175 deletions
diff --git a/sca-cpp/trunk/components/cache/datacache.cpp b/sca-cpp/trunk/components/cache/datacache.cpp
index c26e6eb868..c259ec33c6 100644
--- a/sca-cpp/trunk/components/cache/datacache.cpp
+++ b/sca-cpp/trunk/components/cache/datacache.cpp
@@ -44,7 +44,7 @@ namespace datacache {
/**
* Get an item from the cache.
*/
-const failable<value> get(const value& key, const lambda<value(const list<value>&)> rcache1, const lambda<value(const list<value>&)> wcache1, const lambda<value(const list<value>&)> rcache2, unused const lambda<value(const list<value>&)> wcache2) {
+const failable<value> get(const value& key, const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, const lambda<value(const list<value>&)>& rcache2, unused const lambda<value(const list<value>&)>& wcache2) {
// Lookup level1 cache
const value val1 = rcache1(mklist<value>("get", key));
@@ -68,7 +68,7 @@ const failable<value> get(const value& key, const lambda<value(const list<value>
/**
* Post an item to the cache.
*/
-const failable<value> post(const value& key, const value& val, unused const lambda<value(const list<value>&)> rcache1, const lambda<value(const list<value>&)> wcache1, unused const lambda<value(const list<value>&)> rcache2, const lambda<value(const list<value>&)> wcache2) {
+const failable<value> post(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
const value id = append<value>(key, mklist(mkuuid()));
// Update level1 cache
@@ -83,7 +83,7 @@ const failable<value> post(const value& key, const value& val, unused const lamb
/**
* Put an item into the cache.
*/
-const failable<value> put(const value& key, const value& val, unused const lambda<value(const list<value>&)> rcache1, const lambda<value(const list<value>&)> wcache1, unused const lambda<value(const list<value>&)> rcache2, const lambda<value(const list<value>&)> wcache2) {
+const failable<value> put(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
// Update level1 cache
wcache1(mklist<value>("put", key, val));
@@ -97,7 +97,7 @@ const failable<value> put(const value& key, const value& val, unused const lambd
/**
* Delete an item from the cache.
*/
-const failable<value> del(const value& key, unused const lambda<value(const list<value>&)> rcache1, const lambda<value(const list<value>&)> wcache1, unused const lambda<value(const list<value>&)> rcache2, const lambda<value(const list<value>&)> wcache2) {
+const failable<value> del(const value& key, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
// Delete from level1 cache
wcache1(mklist<value>("delete", key));
diff --git a/sca-cpp/trunk/components/cache/memcache-test.cpp b/sca-cpp/trunk/components/cache/memcache-test.cpp
index 49848dd2a7..85fc339f1a 100644
--- a/sca-cpp/trunk/components/cache/memcache-test.cpp
+++ b/sca-cpp/trunk/components/cache/memcache-test.cpp
@@ -52,6 +52,7 @@ struct getLoop {
getLoop(const value& k, MemCached& ch) : k(k), ch(ch) {
}
const bool operator()() const {
+ gc_scoped_pool p;
assert(get(k, ch) == value(string("CCC")));
return true;
}
@@ -71,6 +72,7 @@ bool testGetPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::memcache::testMemCached();
diff --git a/sca-cpp/trunk/components/cache/memcache.cpp b/sca-cpp/trunk/components/cache/memcache.cpp
index af710696b3..738a6ddd5a 100644
--- a/sca-cpp/trunk/components/cache/memcache.cpp
+++ b/sca-cpp/trunk/components/cache/memcache.cpp
@@ -103,7 +103,7 @@ private:
const list<string> servers(const list<value>& params) {
if (isNil(params))
return list<string>();
- const value s = ((lambda<value(list<value>)>)car(params))(list<value>());
+ const value s = ((lambda<value(const list<value>&)>)car(params))(list<value>());
return cons<string>(s, servers(cdr(params)));
}
diff --git a/sca-cpp/trunk/components/cache/memcache.hpp b/sca-cpp/trunk/components/cache/memcache.hpp
index fe77c26671..f18405b2ec 100644
--- a/sca-cpp/trunk/components/cache/memcache.hpp
+++ b/sca-cpp/trunk/components/cache/memcache.hpp
@@ -49,38 +49,41 @@ namespace memcache {
class MemCached {
public:
MemCached() : owner(false) {
- debug("memcache::memcached");
}
- MemCached(const string host, const int port) : owner(true) {
+ MemCached(const string host, const int port) : p(), owner(true) {
debug(host, "memcache::memcached::host");
debug(port, "memcache::memcached::port");
- apr_pool_create(&pool, NULL);
- apr_memcache_create(pool, 1, 0, &mc);
+ apr_memcache_create(pool(p), 1, 0, &mc);
addServer(host, port);
}
- MemCached(const list<string>& servers) : owner(true) {
+ MemCached(const list<string>& servers) : p(), owner(true) {
debug(servers, "memcache::memcached::servers");
- apr_pool_create(&pool, NULL);
- apr_memcache_create(pool, (apr_uint16_t)length(servers), 0, &mc);
+ apr_memcache_create(pool(p), (apr_uint16_t)length(servers), 0, &mc);
addServers(servers);
}
- MemCached(const MemCached& c) : owner(false), pool(c.pool), mc(c.mc) {
+ MemCached(const MemCached& c) : p(c.p), owner(false), mc(c.mc) {
debug("memcache::memcached::copy");
}
+ const MemCached& operator=(const MemCached& c) {
+ debug("memcache::memcached::operator=");
+ if(this == &c)
+ return *this;
+ p = c.p;
+ owner = false;
+ mc = c.mc;
+ return *this;
+ }
+
~MemCached() {
- debug("memcache::~memcached");
- if (!owner)
- return;
- apr_pool_destroy(pool);
}
private:
+ gc_child_pool p;
bool owner;
- apr_pool_t* pool;
apr_memcache_t* mc;
friend const failable<bool> post(const value& key, const value& val, const MemCached& cache);
@@ -93,7 +96,7 @@ private:
*/
const failable<bool> addServer(const string& host, const int port) {
apr_memcache_server_t *server;
- const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server);
+ const apr_status_t sc = apr_memcache_server_create(pool(p), c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server);
if (sc != APR_SUCCESS) {
ostringstream os;
os << "Couldn't connect to memcached server: " << host << ":" << port;
@@ -176,7 +179,8 @@ const failable<value> get(const value& key, const MemCached& cache) {
const string ks(scheme::writeValue(key));
char *data;
apr_size_t size;
- const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, nospaces(c_str(ks)), &data, &size, NULL);
+ gc_local_pool lp;
+ const apr_status_t rc = apr_memcache_getp(cache.mc, pool(lp), nospaces(c_str(ks)), &data, &size, NULL);
if (rc != APR_SUCCESS) {
ostringstream os;
os << "Couldn't get memcached entry: " << key;
diff --git a/sca-cpp/trunk/components/cache/memocache.cpp b/sca-cpp/trunk/components/cache/memocache.cpp
index 054638e275..e7e52cdc59 100644
--- a/sca-cpp/trunk/components/cache/memocache.cpp
+++ b/sca-cpp/trunk/components/cache/memocache.cpp
@@ -42,7 +42,7 @@ namespace memocache {
/**
* Memoize the value of a function application in a cache.
*/
-const failable<value> memoize(const list<value>& params, const lambda<value(const list<value>&)> relay, const lambda<value(const list<value>&)> cache) {
+const failable<value> memoize(const list<value>& params, const lambda<value(const list<value>&)>& relay, const lambda<value(const list<value>&)>& cache) {
debug(params, "memocache::memoize::params");
// Lookup memoized value from cache
diff --git a/sca-cpp/trunk/components/cache/partitioner.cpp b/sca-cpp/trunk/components/cache/partitioner.cpp
index ea12699977..e3f04ba112 100644
--- a/sca-cpp/trunk/components/cache/partitioner.cpp
+++ b/sca-cpp/trunk/components/cache/partitioner.cpp
@@ -40,7 +40,7 @@ namespace partitioner {
/**
* Return the target partition for a key.
*/
-const failable<lambda<value(const list<value>&)> > partition(const value& key, const lambda<value(const list<value>&)> selector, const list<value>& partitions) {
+const failable<lambda<value(const list<value>&)> > partition(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
// Call the selector component to convert the given key to a partition number
const value p = selector(mklist<value>("get", key, partitions));
@@ -55,7 +55,7 @@ const failable<lambda<value(const list<value>&)> > partition(const value& key, c
/**
* Get an item from a partition.
*/
-const failable<value> get(const value& key, const lambda<value(const list<value>&)> selector, const list<value>& partitions) {
+const failable<value> get(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
// Select partition
const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
@@ -76,7 +76,7 @@ const failable<value> get(const value& key, const lambda<value(const list<value>
/**
* Post an item to a partition.
*/
-const failable<value> post(const value& key, const value& val, const lambda<value(const list<value>&)> selector, const list<value>& partitions) {
+const failable<value> post(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
const value id = append<value>(key, mklist(mkuuid()));
// Select partition
@@ -93,7 +93,7 @@ const failable<value> post(const value& key, const value& val, const lambda<valu
/**
* Put an item into a partition.
*/
-const failable<value> put(const value& key, const value& val, const lambda<value(const list<value>&)> selector, const list<value>& partitions) {
+const failable<value> put(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
// Select partition
const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
@@ -109,7 +109,7 @@ const failable<value> put(const value& key, const value& val, const lambda<value
/**
* Delete an item from a partition.
*/
-const failable<value> del(const value& key, const lambda<value(const list<value>&)> selector, const list<value>& partitions) {
+const failable<value> del(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
// Select partition
const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
diff --git a/sca-cpp/trunk/components/chat/chat-sender.cpp b/sca-cpp/trunk/components/chat/chat-sender.cpp
index 0672292a06..a4cabef8de 100644
--- a/sca-cpp/trunk/components/chat/chat-sender.cpp
+++ b/sca-cpp/trunk/components/chat/chat-sender.cpp
@@ -118,8 +118,8 @@ private:
const failable<value> start(const list<value>& params) {
// Extract the the XMPP JID and password
const list<value> props = params;
- const value jid = ((lambda<value(list<value>)>)car(props))(list<value>());
- const value pass = ((lambda<value(list<value>)>)cadr(props))(list<value>());
+ const value jid = ((lambda<value(const list<value>&)>)car(props))(list<value>());
+ const value pass = ((lambda<value(const list<value>&)>)cadr(props))(list<value>());
// Create an XMPP client session
XMPPClient xc(jid, pass, false);
diff --git a/sca-cpp/trunk/components/chat/chat-sender2.cpp b/sca-cpp/trunk/components/chat/chat-sender2.cpp
index b230d130c1..0e00728022 100644
--- a/sca-cpp/trunk/components/chat/chat-sender2.cpp
+++ b/sca-cpp/trunk/components/chat/chat-sender2.cpp
@@ -41,7 +41,7 @@ namespace sender {
/**
* Post an item to an XMPP JID.
*/
-const failable<value> post(const lambda<value(const list<value>&)> jid, const lambda<value(const list<value>&)> pass, const lambda<value(const list<value>&)> to, const lambda<value(const list<value>&)> msg, const list<value>& params) {
+const failable<value> post(const lambda<value(const list<value>&)>& jid, const lambda<value(const list<value>&)>& pass, const lambda<value(const list<value>&)>& to, const lambda<value(const list<value>&)>& msg, const list<value>& params) {
const value vjid = jid(mklist<value>("get", params));
const value vpass = pass(mklist<value>("get", params));
@@ -69,7 +69,7 @@ const failable<value> post(const lambda<value(const list<value>&)> jid, const la
*/
class chatSender {
public:
- chatSender(const lambda<value(const list<value>&)> jid, const lambda<value(const list<value>&)> pass, const lambda<value(const list<value>&)> to, const lambda<value(const list<value>&)> msg) : jid(jid), pass(pass), to(to), msg(msg) {
+ chatSender(const lambda<value(const list<value>&)>& jid, const lambda<value(const list<value>&)>& pass, const lambda<value(const list<value>&)>& to, const lambda<value(const list<value>&)>& msg) : jid(jid), pass(pass), to(to), msg(msg) {
}
const value operator()(const list<value>& params) const {
diff --git a/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp b/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp
index aac8d69f6c..bfbd32b9ae 100644
--- a/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp
+++ b/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp
@@ -131,8 +131,8 @@ const failable<value> start(const list<value>& params) {
const bool hasRelay = !isNil(cddr(params));
const value rel = hasRelay? car(params) : value(lambda<value(const list<value>&)>());
const list<value> props = hasRelay? cdr(params) : params;
- const value jid = ((lambda<value(list<value>)>)car(props))(list<value>());
- const value pass = ((lambda<value(list<value>)>)cadr(props))(list<value>());
+ const value jid = ((lambda<value(const list<value>&)>)car(props))(list<value>());
+ const value pass = ((lambda<value(const list<value>&)>)cadr(props))(list<value>());
// Create an XMPP client session
XMPPClient xc(jid, pass, false);
diff --git a/sca-cpp/trunk/components/chat/xmpp.hpp b/sca-cpp/trunk/components/chat/xmpp.hpp
index e5f423c270..aa006029fa 100644
--- a/sca-cpp/trunk/components/chat/xmpp.hpp
+++ b/sca-cpp/trunk/components/chat/xmpp.hpp
@@ -76,6 +76,20 @@ public:
debug("chat::xmppclient::copy");
}
+ const XMPPClient& operator=(const XMPPClient& xc) {
+ debug("chat::xmppclient::operator=");
+ if(this == &xc)
+ return *this;
+ owner = false;
+ ctx = xc.ctx;
+ conn = xc.conn;
+ listener = xc.listener;
+ connecting = xc.connecting;
+ connected = xc.connected;
+ disconnecting = xc.disconnecting;
+ return *this;
+ }
+
~XMPPClient() {
debug("chat::~xmppclient");
extern const failable<bool> disconnect(XMPPClient& xc);
@@ -98,7 +112,7 @@ private:
friend const failable<bool> disconnect(XMPPClient& xc);
friend const failable<bool> listen(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc);
- const bool owner;
+ bool owner;
xmpp_ctx_t* ctx;
xmpp_conn_t* conn;
lambda<failable<bool>(const value&, const value&, XMPPClient&)> listener;
diff --git a/sca-cpp/trunk/components/constdb/constdb.cpp b/sca-cpp/trunk/components/constdb/constdb.cpp
index c3b9d63284..6d1cb15baf 100644
--- a/sca-cpp/trunk/components/constdb/constdb.cpp
+++ b/sca-cpp/trunk/components/constdb/constdb.cpp
@@ -102,7 +102,7 @@ private:
*/
const failable<value> start(unused const list<value>& params) {
// Connect to the configured database and table
- const value dbname = ((lambda<value(list<value>)>)car(params))(list<value>());
+ const value dbname = ((lambda<value(const list<value>&)>)car(params))(list<value>());
tinycdb::TinyCDB& cdb = *(new (gc_new<tinycdb::TinyCDB>()) tinycdb::TinyCDB(dbname));
// Return the component implementation lambda function
diff --git a/sca-cpp/trunk/components/constdb/tinycdb.hpp b/sca-cpp/trunk/components/constdb/tinycdb.hpp
index c7d4cf520b..68be0a09dc 100644
--- a/sca-cpp/trunk/components/constdb/tinycdb.hpp
+++ b/sca-cpp/trunk/components/constdb/tinycdb.hpp
@@ -107,7 +107,6 @@ const string absdbname(const string& name) {
class TinyCDB {
public:
TinyCDB() : owner(false), fd(-1) {
- debug("tinycdb::tinycdb");
st.st_ino = 0;
}
@@ -121,8 +120,18 @@ public:
st.st_ino = c.st.st_ino;
}
+ const TinyCDB& operator=(const TinyCDB& c) {
+ debug("tinycdb::tinycdb::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ name = c.name;
+ fd = c.fd;
+ st.st_ino = c.st.st_ino;
+ return *this;
+ }
+
~TinyCDB() {
- debug("tinycdb::~tinycdb");
if (!owner)
return;
if (fd == -1)
diff --git a/sca-cpp/trunk/components/filedb/filedb.cpp b/sca-cpp/trunk/components/filedb/filedb.cpp
index 21b509a3b7..8644a78574 100644
--- a/sca-cpp/trunk/components/filedb/filedb.cpp
+++ b/sca-cpp/trunk/components/filedb/filedb.cpp
@@ -102,8 +102,8 @@ private:
*/
const failable<value> start(const list<value>& params) {
// Connect to the configured database and table
- const value dbname = ((lambda<value(list<value>)>)car(params))(list<value>());
- const value format = ((lambda<value(list<value>)>)cadr(params))(list<value>());
+ const value dbname = ((lambda<value(const list<value>&)>)car(params))(list<value>());
+ const value format = ((lambda<value(const list<value>&)>)cadr(params))(list<value>());
filedb::FileDB& db = *(new (gc_new<filedb::FileDB>()) filedb::FileDB(absdbname(dbname), format));
diff --git a/sca-cpp/trunk/components/filedb/filedb.hpp b/sca-cpp/trunk/components/filedb/filedb.hpp
index a7151eade1..9c3017d0d8 100644
--- a/sca-cpp/trunk/components/filedb/filedb.hpp
+++ b/sca-cpp/trunk/components/filedb/filedb.hpp
@@ -57,7 +57,6 @@ const string absdbname(const string& name) {
class FileDB {
public:
FileDB() : owner(false) {
- debug("filedb::filedb");
}
FileDB(const string& name, const string& format) : owner(true), name(absdbname(name)), format(format) {
@@ -69,8 +68,17 @@ public:
debug("filedb::filedb::copy");
}
+ const FileDB& operator=(const FileDB& c) {
+ debug("filedb::filedb::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ name = c.name;
+ format = c.format;
+ return *this;
+ }
+
~FileDB() {
- debug("filedb::~filedb");
}
private:
diff --git a/sca-cpp/trunk/components/kvdb/client-test.cpp b/sca-cpp/trunk/components/kvdb/client-test.cpp
index fc31a99e69..5f0ef21d00 100644
--- a/sca-cpp/trunk/components/kvdb/client-test.cpp
+++ b/sca-cpp/trunk/components/kvdb/client-test.cpp
@@ -93,8 +93,8 @@ bool testNoSqlDb() {
struct getLoop {
const string path;
const value entry;
- http::CURLSession cs;
- getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ http::CURLSession& cs;
+ getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(uri + path, cs);
diff --git a/sca-cpp/trunk/components/kvdb/kvdb.cpp b/sca-cpp/trunk/components/kvdb/kvdb.cpp
index 24a2fb5a16..0df8f13882 100644
--- a/sca-cpp/trunk/components/kvdb/kvdb.cpp
+++ b/sca-cpp/trunk/components/kvdb/kvdb.cpp
@@ -102,7 +102,7 @@ private:
*/
const failable<value> start(unused const list<value>& params) {
// Connect to the configured database and table
- const value dbname = ((lambda<value(list<value>)>)car(params))(list<value>());
+ const value dbname = ((lambda<const value(list<value>&)>)car(params))(list<value>());
leveldb::LevelDB& cdb = *(new (gc_new<leveldb::LevelDB>()) leveldb::LevelDB(dbname));
// Return the component implementation lambda function
diff --git a/sca-cpp/trunk/components/kvdb/leveldb.hpp b/sca-cpp/trunk/components/kvdb/leveldb.hpp
index 8105f86ec4..05a89a76f7 100644
--- a/sca-cpp/trunk/components/kvdb/leveldb.hpp
+++ b/sca-cpp/trunk/components/kvdb/leveldb.hpp
@@ -121,6 +121,17 @@ public:
st.st_ino = c.st.st_ino;
}
+ const LevelDB& operator=(const LevelDB& c) {
+ debug("leveldb::leveldb::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ name = c.name;
+ fd = c.fd;
+ st.st_ino = c.st.st_ino;
+ return *this;
+ }
+
~LevelDB() {
debug("leveldb::~leveldb");
if (!owner)
diff --git a/sca-cpp/trunk/components/log/log.cpp b/sca-cpp/trunk/components/log/log.cpp
index 2e7742cfd7..f7f7086192 100644
--- a/sca-cpp/trunk/components/log/log.cpp
+++ b/sca-cpp/trunk/components/log/log.cpp
@@ -75,8 +75,8 @@ const failable<value> start(const list<value>& params) {
scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464));
// Extract the configured category
- const value host = ((lambda<value(list<value>)>)car(params))(list<value>());
- const value category = ((lambda<value(list<value>)>)cadr(params))(list<value>());
+ const value host = ((lambda<value(const list<value>&)>)car(params))(list<value>());
+ const value category = ((lambda<value(const list<value>&)>)cadr(params))(list<value>());
debug(host, "log::start::host");
debug(category, "log::start::category");
diff --git a/sca-cpp/trunk/components/log/logger.cpp b/sca-cpp/trunk/components/log/logger.cpp
index d7a54507fb..d7969036ab 100644
--- a/sca-cpp/trunk/components/log/logger.cpp
+++ b/sca-cpp/trunk/components/log/logger.cpp
@@ -73,8 +73,8 @@ const failable<value> start(const list<value>& params) {
// Extract the configured relay service and category
const value rel = car(params);
- const value host = ((lambda<value(list<value>)>)cadr(params))(list<value>());
- const value category = ((lambda<value(list<value>)>)caddr(params))(list<value>());
+ const value host = ((lambda<value(const list<value>&)>)cadr(params))(list<value>());
+ const value category = ((lambda<value(const list<value>&)>)caddr(params))(list<value>());
debug(host, "logger::start::host");
debug(category, "logger::start::category");
diff --git a/sca-cpp/trunk/components/log/scribe-cat.cpp b/sca-cpp/trunk/components/log/scribe-cat.cpp
index fbfdaca533..254e2167ae 100644
--- a/sca-cpp/trunk/components/log/scribe-cat.cpp
+++ b/sca-cpp/trunk/components/log/scribe-cat.cpp
@@ -38,12 +38,12 @@ namespace scribecat {
int cat(const string& host, const string& category, const string& type) {
// Connect to Scribe
- scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464));
+ scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe(host, 1464));
// Read lines from stdin and log them
char buf[8193];
for (;;) {
- gc_scoped_pool();
+ gc_scoped_pool p;
// Write line prefix
ostringstream os;
diff --git a/sca-cpp/trunk/components/log/scribe.hpp b/sca-cpp/trunk/components/log/scribe.hpp
index 5ae8a50776..0f0570be64 100644
--- a/sca-cpp/trunk/components/log/scribe.hpp
+++ b/sca-cpp/trunk/components/log/scribe.hpp
@@ -66,7 +66,6 @@ namespace scribe {
class Scribe {
public:
Scribe() : owner(false) {
- debug("scribe::scribe");
}
Scribe(const string host, const int port) : owner(true) {
@@ -80,9 +79,18 @@ public:
client = c.client;
transport = c.transport;
}
+
+ const Scribe& operator=(const Scribe& c) {
+ debug("scribe::scribe::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ client = c.client;
+ transport = c.transport;
+ return *this;
+ }
~Scribe() {
- debug("scribe::~scribe");
if (!owner)
return;
try {
diff --git a/sca-cpp/trunk/components/queue/qpid.hpp b/sca-cpp/trunk/components/queue/qpid.hpp
index 63f27d2519..ef53c529e8 100644
--- a/sca-cpp/trunk/components/queue/qpid.hpp
+++ b/sca-cpp/trunk/components/queue/qpid.hpp
@@ -65,6 +65,15 @@ public:
debug("queue::qpidonnection::copy");
}
+ const QpidConnection& operator=(const QpidConnection& qc) {
+ debug("queue::qpidonnection::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ c = qc.c;
+ return *this;
+ }
+
~QpidConnection() {
debug("queue::~qpidonnection");
if (!owner)
diff --git a/sca-cpp/trunk/components/queue/queue-listener.cpp b/sca-cpp/trunk/components/queue/queue-listener.cpp
index 3c30e7feca..483d0de65a 100644
--- a/sca-cpp/trunk/components/queue/queue-listener.cpp
+++ b/sca-cpp/trunk/components/queue/queue-listener.cpp
@@ -123,9 +123,9 @@ private:
const failable<value> start(const list<value>& params) {
// Extract the relay reference and the AMQP key and queue name
const value rel = car(params);
- const value pk = ((lambda<value(list<value>)>)cadr(params))(list<value>());
+ const value pk = ((lambda<value(const list<value>&)>)cadr(params))(list<value>());
const value key = isList(pk)? (list<value>)pk : mklist<value>(pk);
- const value qname = ((lambda<value(list<value>)>)caddr(params))(list<value>());
+ const value qname = ((lambda<value(const list<value>&)>)caddr(params))(list<value>());
// Create an AMQP session
QpidConnection qc(false);
diff --git a/sca-cpp/trunk/components/queue/queue-sender.cpp b/sca-cpp/trunk/components/queue/queue-sender.cpp
index ff2ede1057..202a0e4435 100644
--- a/sca-cpp/trunk/components/queue/queue-sender.cpp
+++ b/sca-cpp/trunk/components/queue/queue-sender.cpp
@@ -48,7 +48,7 @@ const failable<value> post(const list<value>& params) {
QpidSession qs(qc);
// Post the item
- const value pk = ((lambda<value(list<value>)>)caddr(params))(list<value>());
+ const value pk = ((lambda<value(const list<value>&)>)caddr(params))(list<value>());
const value key = isList(pk)? append<value>(pk, (list<value>)car(params)) : cons<value>(pk, (list<value>)car(params));
debug(key, "queue::post::key");
debug(cadr(params), "queue::post::value");
diff --git a/sca-cpp/trunk/components/sqldb/pgsql.hpp b/sca-cpp/trunk/components/sqldb/pgsql.hpp
index d38af54c97..581cd943e6 100644
--- a/sca-cpp/trunk/components/sqldb/pgsql.hpp
+++ b/sca-cpp/trunk/components/sqldb/pgsql.hpp
@@ -91,6 +91,17 @@ public:
debug("pgsql::pgsql::copy");
}
+ const PGSql& operator=(const PGSql& c) {
+ debug("pgsql::pgsql::operator=");
+ if(this == &c)
+ return *this;
+ owner = false;
+ conn = c.conn;
+ conninfo = c.conninfo;
+ table = c.table;
+ return *this;
+ }
+
~PGSql() {
debug("pgsql::~pgsql");
if (!owner)
@@ -104,7 +115,7 @@ private:
bool owner;
PGconn *conn;
string conninfo;
- const string table;
+ string table;
string kname;
string vname;
diff --git a/sca-cpp/trunk/components/sqldb/sqldb.cpp b/sca-cpp/trunk/components/sqldb/sqldb.cpp
index bbf118385e..9925897693 100644
--- a/sca-cpp/trunk/components/sqldb/sqldb.cpp
+++ b/sca-cpp/trunk/components/sqldb/sqldb.cpp
@@ -120,8 +120,8 @@ private:
*/
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>());
+ const value conninfo = ((lambda<value(const list<value>&)>)car(params))(list<value>());
+ const value table = ((lambda<value(const list<value>&)>)cadr(params))(list<value>());
const perthread_ptr<pgsql::PGSql> pg(lambda<gc_ptr<pgsql::PGSql>()>(newPGSql(conninfo, table)));
// Return the component implementation lambda function
diff --git a/sca-cpp/trunk/components/webservice/axis2.hpp b/sca-cpp/trunk/components/webservice/axis2.hpp
index 7630b54295..9bad109ff0 100644
--- a/sca-cpp/trunk/components/webservice/axis2.hpp
+++ b/sca-cpp/trunk/components/webservice/axis2.hpp
@@ -65,6 +65,15 @@ public:
debug("webservice::axis2context::copy");
}
+ const Axis2Context& operator=(const Axis2Context& ax) {
+ debug("webservice::axis2context::operator=");
+ if(this == &ax)
+ return *this;
+ env = ax.env;
+ owner = false;
+ return *this;
+ }
+
Axis2Context(const axutil_env_t* env) : env(const_cast<axutil_env_t*>(env)), owner(false) {
debug("webservice::axis2context::env");
}
diff --git a/sca-cpp/trunk/etc/httpd-ipcrm b/sca-cpp/trunk/etc/httpd-ipcrm
index b457e7385f..860b724296 100755
--- a/sca-cpp/trunk/etc/httpd-ipcrm
+++ b/sca-cpp/trunk/etc/httpd-ipcrm
@@ -19,5 +19,6 @@
# Remove ipcs created by httpd
-ipcs -s | grep 0x | awk '{ print $2 }' | xargs -i -t ipcrm -s {}
+id=`id -un`
+ipcs -s | grep "$id" | grep "0x" | awk '{ print $2 }' | xargs -i -t ipcrm -s {}
diff --git a/sca-cpp/trunk/hosting/server/client-test.cpp b/sca-cpp/trunk/hosting/server/client-test.cpp
new file mode 100644
index 0000000000..c0a01b5237
--- /dev/null
+++ b/sca-cpp/trunk/hosting/server/client-test.cpp
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test HTTP client functions.
+ */
+
+#include "stream.hpp"
+#include "string.hpp"
+#include "client-test.hpp"
+
+int main(const int argc, const char** argv) {
+ tuscany::cout << "Testing..." << tuscany::endl;
+ tuscany::server::testURI = argc > 1? argv[1] : "https://jane:jane@www.example.com:8453";
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/trunk/kernel/dynlib.hpp b/sca-cpp/trunk/kernel/dynlib.hpp
index 484de3d666..69359b4dae 100644
--- a/sca-cpp/trunk/kernel/dynlib.hpp
+++ b/sca-cpp/trunk/kernel/dynlib.hpp
@@ -59,6 +59,15 @@ public:
lib(const lib& l) : name(l.name), h(l.h), owner(false) {
}
+ const lib& operator=(const lib& l) {
+ if(this == &l)
+ return *this;
+ name = l.name;
+ h = l.h;
+ owner = false;
+ return *this;
+ }
+
~lib() {
if (!owner)
return;
@@ -70,7 +79,7 @@ public:
private:
template<typename S> friend const failable<lambda<S> > dynlambda(const string& name, const lib& l);
- const string name;
+ string name;
failable<void*> h;
bool owner;
};
diff --git a/sca-cpp/trunk/kernel/fstream.hpp b/sca-cpp/trunk/kernel/fstream.hpp
index 5ea9df2d62..4f7f5152aa 100644
--- a/sca-cpp/trunk/kernel/fstream.hpp
+++ b/sca-cpp/trunk/kernel/fstream.hpp
@@ -78,6 +78,14 @@ public:
ofstream(const ofstream& os) : file(os.file), owner(false) {
}
+ const ofstream& operator=(const ofstream& os) {
+ if(this == &os)
+ return *this;
+ file = os.file;
+ owner = false;
+ return *this;
+ }
+
~ofstream() {
if (!owner)
return;
@@ -127,6 +135,14 @@ public:
ifstream(const ifstream& is) : file(is.file), owner(false) {
}
+ const ifstream& operator=(const ifstream& is) {
+ if(this == &is)
+ return *this;
+ file = is.file;
+ owner = false;
+ return *this;
+ }
+
~ifstream() {
if (!owner)
return;
@@ -351,7 +367,7 @@ const bool debug_isLogging() {
* Log a debug message.
*/
const bool debugLog(const string& msg) {
- gc_scoped_pool();
+ gc_scoped_pool p;
cdebug << msg << endl;
return true;
}
@@ -360,7 +376,7 @@ const bool debugLog(const string& msg) {
* Log a debug message and a value.
*/
template<typename V> const bool debugLog(const V& v, const string& msg) {
- gc_scoped_pool();
+ gc_scoped_pool p;
cdebug << msg << ": " << v << endl;
return true;
}
@@ -369,7 +385,7 @@ template<typename V> const bool debugLog(const V& v, const string& msg) {
* Log a debug message and two values.
*/
template<typename V, typename W> const bool debugLog(const V& v, const W& w, const string& msg) {
- gc_scoped_pool();
+ gc_scoped_pool p;
cdebug << msg << ": " << v << " : " << w << endl;
return true;
}
diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp
index 260688f4ff..32ad8160cc 100644
--- a/sca-cpp/trunk/kernel/gc.hpp
+++ b/sca-cpp/trunk/kernel/gc.hpp
@@ -149,22 +149,14 @@ public:
private:
friend apr_pool_t* pool(const gc_pool& pool);
friend class gc_global_pool_t;
+ friend class gc_child_pool;
+ friend class gc_local_pool;
friend class gc_scoped_pool;
apr_pool_t* apr_pool;
};
/**
- * Make a new APR pool.
- */
-apr_pool_t* mkpool() {
- apr_pool_t* p = NULL;
- apr_pool_create(&p, NULL);
- assertOrFail(p != NULL);
- return p;
-}
-
-/**
* Return the APR pool used by a gc_pool.
*/
apr_pool_t* pool(const gc_pool& pool) {
@@ -172,16 +164,6 @@ apr_pool_t* pool(const gc_pool& pool) {
}
/**
- * Destroy a memory pool.
- */
-const bool destroy(const gc_pool& p) {
- if (pool(p) == NULL)
- return false;
- apr_pool_destroy(pool(p));
- return true;
-}
-
-/**
* Maintain a stack of memory pools.
*/
#ifdef WANT_THREADS
@@ -244,19 +226,77 @@ apr_pool_t* gc_current_pool() {
}
/**
- * A memory pool scope, used to setup a scope in which a particular pool
- * will be used for all allocations.
+ * A child memory pool, which will be destroyed when its parent pool is destroyed.
+ */
+class gc_child_pool : public gc_pool {
+public:
+
+ gc_child_pool() : gc_pool(NULL), owner(true) {
+ apr_pool_create(&apr_pool, gc_current_pool());
+ assertOrFail(apr_pool != NULL);
+ }
+
+ gc_child_pool(const gc_child_pool& p) : gc_pool(p.apr_pool), owner(false) {
+ }
+
+ const gc_child_pool& operator=(const gc_child_pool& p) {
+ if(this == &p)
+ return *this;
+ apr_pool = p.apr_pool;
+ owner = false;
+ return *this;
+ }
+
+
+private:
+ bool owner;
+};
+
+/**
+ * A local pool scope, which will be destroyed when exiting the current scope.
+ */
+class gc_local_pool : public gc_pool {
+public:
+
+ gc_local_pool() : gc_pool(NULL), owner(true) {
+ apr_pool_create(&apr_pool, gc_current_pool());
+ assertOrFail(apr_pool != NULL);
+ }
+
+ ~gc_local_pool() {
+ if (owner)
+ apr_pool_destroy(apr_pool);
+ }
+
+ gc_local_pool(const gc_local_pool& p) : gc_pool(p.apr_pool), owner(false) {
+ }
+
+ const gc_local_pool& operator=(const gc_local_pool& p) {
+ if(this == &p)
+ return *this;
+ apr_pool = p.apr_pool;
+ owner = false;
+ return *this;
+ }
+
+private:
+ bool owner;
+};
+
+/**
+ * A memory pool scope, used to setup a scope in which a particular pool will be
+ * used for all allocations. Will be destroyed when existing the current scope.
*/
class gc_scoped_pool : public gc_pool {
public:
gc_scoped_pool() : gc_pool(NULL), prev(gc_current_pool()), owner(true) {
- apr_pool_create(&apr_pool, NULL);
+ apr_pool_create(&apr_pool, prev);
assertOrFail(apr_pool != NULL);
gc_push_pool(apr_pool);
}
- gc_scoped_pool(apr_pool_t* pool) : gc_pool(pool), prev(gc_current_pool()), owner(false) {
+ gc_scoped_pool(apr_pool_t* p) : gc_pool(p), prev(gc_current_pool()), owner(false) {
gc_push_pool(apr_pool);
}
@@ -266,10 +306,19 @@ public:
gc_pop_pool(prev);
}
-private:
- gc_scoped_pool(const gc_scoped_pool& pool) : gc_pool(pool.apr_pool), prev(NULL), owner(false) {
+ gc_scoped_pool(const gc_scoped_pool& p) : gc_pool(p.apr_pool), prev(p.prev), owner(false) {
}
+ const gc_scoped_pool& operator=(const gc_scoped_pool& p) {
+ if(this == &p)
+ return *this;
+ apr_pool = p.apr_pool;
+ prev = p.prev;
+ owner = false;
+ return *this;
+ }
+
+private:
apr_pool_t* prev;
bool owner;
};
diff --git a/sca-cpp/trunk/kernel/hash-test.cpp b/sca-cpp/trunk/kernel/hash-test.cpp
index b794e38920..4e6a3654e5 100644
--- a/sca-cpp/trunk/kernel/hash-test.cpp
+++ b/sca-cpp/trunk/kernel/hash-test.cpp
@@ -121,6 +121,7 @@ bool testHashPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::testCrc32hash();
diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp
index 7bde4fb526..4d2ca2ba81 100644
--- a/sca-cpp/trunk/kernel/kernel-test.cpp
+++ b/sca-cpp/trunk/kernel/kernel-test.cpp
@@ -575,6 +575,7 @@ bool testDynLib() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::testLambda();
diff --git a/sca-cpp/trunk/kernel/lambda-test.cpp b/sca-cpp/trunk/kernel/lambda-test.cpp
index e17cf57e67..05a16c2eb8 100644
--- a/sca-cpp/trunk/kernel/lambda-test.cpp
+++ b/sca-cpp/trunk/kernel/lambda-test.cpp
@@ -87,6 +87,7 @@ bool testCppPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
#ifdef HAS_CXX0X_LAMBDAS
diff --git a/sca-cpp/trunk/kernel/mem-test.cpp b/sca-cpp/trunk/kernel/mem-test.cpp
index e9a2f85ec6..668dabe749 100644
--- a/sca-cpp/trunk/kernel/mem-test.cpp
+++ b/sca-cpp/trunk/kernel/mem-test.cpp
@@ -151,6 +151,7 @@ bool testStdAllocPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::testPoolAllocPerf();
diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp
index 657a809c1c..b67e92ad79 100644
--- a/sca-cpp/trunk/kernel/monad.hpp
+++ b/sca-cpp/trunk/kernel/monad.hpp
@@ -26,6 +26,8 @@
* Simple monad implementations.
*/
+#include <execinfo.h>
+#include <cxxabi.h>
#include "function.hpp"
#include "string.hpp"
#include "stream.hpp"
@@ -278,38 +280,134 @@ template<typename V, typename F, typename C> const lambda<failable<V, F, C>(cons
}
/**
+ * Demangle a C++ function name.
+ */
+const string demangleFrame(const char* fun) {
+ int status;
+ char* name = abi::__cxa_demangle(fun, 0, 0, &status);
+ if (name == NULL)
+ return fun;
+ const string s = name;
+ free(name);
+ return s;
+}
+
+/**
+ * Format a backtrace frame.
+ */
+const char* formatFrameFile(const char* file) {
+ const char* s = strrchr(file, '/');
+ return s == NULL? file : s + 1;
+}
+
+const string formatFrame(const char* symbol) {
+#ifdef __clang__
+ // Mac OS X CLang/LLVM stack frame format
+ // 0 kernel-test 0x000000010d440179 _ZN7tuscany9mkfailureINS_5valueENS_6stringEiEEKNS_8failableIT_T0_T1_EERKS5_RKS6_b + 265
+ char nb[3];
+ char file[256];
+ char addr[32];
+ char fun[256];
+ char offset[16];
+ if (sscanf(symbol, "%2s %255s %31s %255s %*[+] %15s", nb, file, addr, fun, offset) == 5) {
+ char buf[1024];
+ if (debug_islogging())
+ sprintf(buf, "%.255s %.31s %.511s + %.15s", formatFrameFile(file), addr, c_str(demangleFrame(fun)), offset);
+ else
+ sprintf(buf, "%.255s %.31s", formatFrameFile(file), addr);
+ return buf;
+ }
+#else
+ // Linux GCC stack frame format
+ // ./kernel-test(_ZN7tuscany9mkfailureINS_5valueENS_6stringEiEEKNS_8failableIT_T0_T1_EERKS5_RKS6_b+0x23d) [0xb7197afd]
+ char file[256];
+ char fun[256];
+ char offset[16];
+ char addr[32];
+ if (sscanf(symbol, "%[^(]%*[(]%[^+]%*[+]%[^)]%*[)] %*[[]%[^]]%*[]]", file, fun, offset, addr) == 4) {
+ char buf[1024];
+ if (debug_islogging())
+ sprintf(buf, "%.255s %.31s %.511s + %.15s", formatFrameFile(file), addr, c_str(demangleFrame(fun)), offset);
+ else
+ sprintf(buf, "%.255s %.31s", formatFrameFile(file), addr);
+ return buf;
+ }
+ if (sscanf(symbol, "%[^(]%*[(]%*[^)]%*[)] %*[[]%[^]]%*[]]", file, addr) == 2) {
+ char buf[512];
+ sprintf(buf, "%.255s %.31s", formatFrameFile(file), addr);
+ return buf;
+ }
+ if (sscanf(symbol, "%[^(]%*[(]%*[)] %*[[]%[^]]%*[]]", file, addr) == 2) {
+ char buf[512];
+ sprintf(buf, "%.255s %.31s", formatFrameFile(file), addr);
+ return buf;
+ }
+#endif
+ return symbol;
+}
+
+/**
+ * Log backtrace frames.
+ */
+const bool logFrames(char** symbols, const int frames, const bool log) {
+ if (frames == 0)
+ return true;
+#ifdef WANT_MAINTAINER_LOG
+ if (!log)
+ debug(formatFrame(*symbols), "failable::backtrace");
+#endif
+ if (log)
+ cfailure << "failable::backtrace: " << formatFrame(*symbols) << endl;
+ return logFrames(symbols + 1, frames - 1, log);
+}
+
+/**
+ * Log a backtrace.
+ */
+const bool logBacktrace(void** callstack, const int frames, const bool log) {
+ char** symbols = backtrace_symbols(callstack, frames);
+ logFrames(symbols, frames, log);
+ free(symbols);
+ return true;
+}
+
+/**
* Returns a failable monad with a failure in it.
*/
template<typename V, typename F, typename C> const failable<V, F, C> mkfailure(const F& f, const C& c, const bool log = true) {
#ifdef WANT_MAINTAINER_LOG
- if (!log)
+ if (!log) {
+ // Log the failure
debug(f, "failable::mkfailure");
+
+ // Log the call stack
+ void* callstack[16];
+ const int frames = backtrace(callstack, 16);
+ logBacktrace(callstack, frames, log);
+ }
#endif
if (log) {
ostringstream os;
os << f;
- if (length(str(os)) != 0)
- cfailure << "failable::mkfailure" << ": " << f << " : " << c << endl;
+ if (length(str(os)) != 0) {
+ // Log the failure
+ cfailure << "failable::mkfailure: " << f << " : " << c << endl;
+
+ // Print the call stack
+ void* callstack[16];
+ const int frames = backtrace(callstack, 16);
+ logBacktrace(callstack, frames, log);
+ }
}
return failable<V, F, C>(false, f, c);
}
template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const int c = -1, const bool log = true) {
-#ifdef WANT_MAINTAINER_LOG
- if (!log)
- debug(f, c, "failable::mkfailure");
-#endif
- if (log) {
- ostringstream os;
- os << f;
- if (length(str(os)) != 0)
- cfailure << "failable::mkfailure: " << str(os) << " : " << c << endl;
- }
- return failable<V, F>(false, f, c);
+ return mkfailure<V, F, int>(f, c, log);
}
template<typename V> const failable<V> mkfailure(const char* f, const int c = -1, const bool log = true) {
- return mkfailure<V, string>(string(f), c, log);
+ return mkfailure<V, string, int>(string(f), c, log);
}
template<typename V> const failable<V> mkfailure() {
diff --git a/sca-cpp/trunk/kernel/parallel-test.cpp b/sca-cpp/trunk/kernel/parallel-test.cpp
index 59cfd81978..28e484d42b 100644
--- a/sca-cpp/trunk/kernel/parallel-test.cpp
+++ b/sca-cpp/trunk/kernel/parallel-test.cpp
@@ -33,8 +33,6 @@
namespace tuscany {
-#ifdef WANT_THREADS
-
int inci = 0;
struct incPerf {
@@ -46,6 +44,24 @@ struct incPerf {
}
};
+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;
+ return true;
+ }
+};
+
+#ifdef WANT_THREADS
+
int addi = 0;
struct addAndFetchPerf {
@@ -71,21 +87,7 @@ struct mutexPerf {
}
};
-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;
- return true;
- }
-};
+#endif
bool testAtomicPerf() {
const int count = 100000;
@@ -94,6 +96,7 @@ bool testAtomicPerf() {
cout << "Non-atomic inc test " << time(l, 1000, count) << " ms" << endl;
assert(inci == count + 1000);
}
+#ifdef WANT_THREADS
{
const lambda<bool()> l = addAndFetchPerf();
cout << "Atomic inc test " << time(l, 1000, count) << " ms" << endl;
@@ -107,6 +110,7 @@ bool testAtomicPerf() {
assert(muxi == count + 1000);
pthread_mutex_destroy(&mutex);
}
+#endif
{
const lambda<bool()> l = tlsPerf();
cout << "Thread local inc test " << time(l, 1000, count) << " ms" << endl;
@@ -115,6 +119,8 @@ bool testAtomicPerf() {
return true;
}
+#ifdef WANT_THREADS
+
const int mtsquare(const int x) {
for(int i = 0; i < 10000000; i++)
;
@@ -239,10 +245,11 @@ bool testWorker() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
-#ifdef WANT_THREADS
tuscany::testAtomicPerf();
+#ifdef WANT_THREADS
tuscany::testWorker();
#else
tuscany::cout << "Skipped multi-thread tests" << tuscany::endl;
diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp
index 57754a33e6..3be4d3bc8e 100644
--- a/sca-cpp/trunk/kernel/parallel.hpp
+++ b/sca-cpp/trunk/kernel/parallel.hpp
@@ -429,24 +429,24 @@ private:
}
#else
- int createkey() {
- return 0;
+ gc_ptr<gc_ptr<T> > createkey() {
+ return new (gc_new<gc_ptr<T> >()) gc_ptr<T>();
}
- bool deletekey(unused int k) {
+ bool deletekey(unused gc_ptr<gc_ptr<T> > k) {
return true;
}
bool set(const gc_ptr<T>& v) {
- val = v;
+ *key = v;
return true;
}
gc_ptr<T> get() const {
- if (val != NULL || !managed)
- return val;
- val = cl();
- return val;
+ if (*key != NULL || !managed)
+ return *key;
+ *key = cl();
+ return *key;
}
#endif
@@ -454,8 +454,7 @@ private:
#ifdef WANT_THREADS
pthread_key_t key;
#else
- int key;
- gc_ptr<T> val;
+ gc_ptr<gc_ptr<T> >key;
#endif
bool owner;
diff --git a/sca-cpp/trunk/kernel/perf.hpp b/sca-cpp/trunk/kernel/perf.hpp
index 82d0ddad03..04aad06664 100644
--- a/sca-cpp/trunk/kernel/perf.hpp
+++ b/sca-cpp/trunk/kernel/perf.hpp
@@ -42,10 +42,8 @@ struct timeLambda {
timeLambda(const lambda<bool()>& f) : f(f) {
}
bool operator()(const long count) const {
- if (count == 0)
- return true;
- f();
- (*this)(count - 1);
+ for (long i = 0; i < count; i++)
+ f();
return true;
}
};
diff --git a/sca-cpp/trunk/kernel/string-test.cpp b/sca-cpp/trunk/kernel/string-test.cpp
index e691d93dfb..b6f016b294 100644
--- a/sca-cpp/trunk/kernel/string-test.cpp
+++ b/sca-cpp/trunk/kernel/string-test.cpp
@@ -185,6 +185,7 @@ bool testStringPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::testCopies();
diff --git a/sca-cpp/trunk/kernel/xml-test.cpp b/sca-cpp/trunk/kernel/xml-test.cpp
index c505cae9cf..0523cc74a6 100644
--- a/sca-cpp/trunk/kernel/xml-test.cpp
+++ b/sca-cpp/trunk/kernel/xml-test.cpp
@@ -221,6 +221,7 @@ bool testValues() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::testReadXML();
diff --git a/sca-cpp/trunk/kernel/xml.hpp b/sca-cpp/trunk/kernel/xml.hpp
index 14549e5dfc..d00a2905fb 100644
--- a/sca-cpp/trunk/kernel/xml.hpp
+++ b/sca-cpp/trunk/kernel/xml.hpp
@@ -78,6 +78,19 @@ public:
debug("xml::XMLReader::copy");
}
+ const XMLReader& operator=(const XMLReader& r) {
+ debug("xml::XMLReader::operator=");
+ if(this == &r)
+ return *this;
+ xml = r.xml;
+ owner = false;
+ tokenType = r.tokenType;
+ isEmptyElement = r.isEmptyElement;
+ hasValue = r.hasValue;
+ hasAttributes = r.hasAttributes;
+ return *this;
+ }
+
~XMLReader() {
if (!owner)
return;
@@ -112,8 +125,8 @@ public:
}
private:
- const xmlTextReaderPtr xml;
- const bool owner;
+ xmlTextReaderPtr xml;
+ bool owner;
int tokenType;
bool isEmptyElement;
bool hasValue;
diff --git a/sca-cpp/trunk/modules/atom/atom-test.cpp b/sca-cpp/trunk/modules/atom/atom-test.cpp
index e00c75a62f..479ed64f29 100644
--- a/sca-cpp/trunk/modules/atom/atom-test.cpp
+++ b/sca-cpp/trunk/modules/atom/atom-test.cpp
@@ -273,6 +273,7 @@ bool testFeed() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::atom::testEntry();
diff --git a/sca-cpp/trunk/modules/js/eval.hpp b/sca-cpp/trunk/modules/js/eval.hpp
index 21fa274d2c..f8f4cbe598 100644
--- a/sca-cpp/trunk/modules/js/eval.hpp
+++ b/sca-cpp/trunk/modules/js/eval.hpp
@@ -65,7 +65,7 @@ public:
JSRuntime() {
// Create JS runtime
debug("js::jsruntime");
- rt = JS_NewRuntime(32L * 1024L * 1024L);
+ rt = JS_NewRuntime(1L * 512L * 1024L);
if(rt == NULL)
cleanup();
}
@@ -114,14 +114,19 @@ public:
debug("js::jscontext");
if (jsContext != NULL) {
cx = jsContext;
+ JS_BeginRequest(cx);
return;
}
+ debug("js::jsnewcontext");
cx = JS_NewContext(jsRuntime, 8192);
if(cx == NULL)
return;
+ JS_BeginRequest(cx);
+
JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, reportError);
+ //JS_SetGCZeal(cx, 2);
// Create global JS object
global = JS_NewCompartmentAndGlobalObject(cx, &jsGlobalClass, NULL);
@@ -140,8 +145,6 @@ public:
~JSContext() {
debug("js::~jscontext");
- if (cx != NULL)
- JS_MaybeGC(cx);
cleanup();
}
@@ -156,8 +159,12 @@ public:
private:
bool cleanup() {
if(cx != NULL) {
- if (cx != jsContext)
+ JS_MaybeGC(cx);
+ JS_EndRequest(cx);
+ if (cx != jsContext) {
+ debug("js::jsdestroycontext");
JS_DestroyContext(cx);
+ }
cx = NULL;
}
return true;
diff --git a/sca-cpp/trunk/modules/js/js-test.cpp b/sca-cpp/trunk/modules/js/js-test.cpp
index 9cbf000ac3..a7e5597610 100644
--- a/sca-cpp/trunk/modules/js/js-test.cpp
+++ b/sca-cpp/trunk/modules/js/js-test.cpp
@@ -42,6 +42,7 @@ bool testJSEval() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::js::testJSEval();
diff --git a/sca-cpp/trunk/modules/json/json-test.cpp b/sca-cpp/trunk/modules/json/json-test.cpp
index 61aac4ee02..945b6c072c 100644
--- a/sca-cpp/trunk/modules/json/json-test.cpp
+++ b/sca-cpp/trunk/modules/json/json-test.cpp
@@ -27,6 +27,7 @@
#include "stream.hpp"
#include "string.hpp"
#include "json.hpp"
+#include "perf.hpp"
namespace tuscany {
namespace json {
@@ -74,6 +75,7 @@ const string jsarray("{\n"
"}");
bool testJSON() {
+ gc_scoped_pool pool;
const js::JSContext cx;
{
@@ -217,6 +219,7 @@ const string jsechores("{\n"
"}");
bool testJSONRPC() {
+ gc_scoped_pool pool;
js::JSContext cx;
{
const string lm("{\"id\": 1, \"method\": \"test\", \"params\": []}");
@@ -283,14 +286,49 @@ bool testJSONRPC() {
return true;
}
+struct testReadWrite {
+ testReadWrite() {
+ }
+ const bool operator()() const {
+ gc_scoped_pool pool;
+ js::JSContext cx;
+
+ const list<value> ad = mklist<value>(mklist<value>(attribute, "city", string("san francisco")), mklist<value>(attribute, "state", string("ca")));
+ const list<value> ac = mklist<value>(mklist<value>(element, "id", string("1234")), mklist<value>(attribute, "balance", 1000));
+ const list<value> cr = mklist<value>(mklist<value> (attribute, "name", string("jdoe")), cons<value>(element, cons<value>("address", ad)), cons<value>(element, cons<value>("account", ac)));
+ const list<value> c = mklist<value>(cons<value>(element, cons<value>("customer", cr)));
+
+ ostringstream os;
+ writeJSON<ostream*>(jsonWriter, &os, c, cx);
+ assert(str(os) == jscustomer);
+
+ istringstream is(jscustomer);
+ const list<string> il = streamList(is);
+ const list<value> r = content(readJSON(il, cx));
+ assert(r == c);
+ return true;
+ }
+};
+
+bool testJSONPerf() {
+ gc_scoped_pool pool;
+
+ const lambda<bool()> rwl = lambda<bool()>(testReadWrite());
+ cout << "JSON read + write test " << time(rwl, 5, 200) << " ms" << endl;
+
+ return true;
+}
+
}
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::json::testJSON();
tuscany::json::testJSONRPC();
+ tuscany::json::testJSONPerf();
tuscany::cout << "OK" << tuscany::endl;
diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp
index da5d226789..5c0be7d261 100644
--- a/sca-cpp/trunk/modules/python/eval.hpp
+++ b/sca-cpp/trunk/modules/python/eval.hpp
@@ -26,6 +26,8 @@
* Python script evaluation logic.
*/
#if PYTHON_VERSION == 27
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
#include <python2.7/Python.h>
#include <python2.7/frameobject.h>
#include <python2.7/traceback.h>
@@ -71,15 +73,12 @@ public:
PythonRuntime() {
debug("python::pythonruntime");
+ // Save current process id
#ifdef WANT_THREADS
pthread_mutex_init(&mutex, NULL);
-
-#ifdef IS_DARWIN
- // Save current process id
pthread_mutex_init(&pidmutex, NULL);
- pid = processId();
-#endif
#endif
+ pid = processId();
// Initialize the Python interpreter
#ifdef IS_DARWIN
@@ -134,11 +133,9 @@ public:
private:
#ifdef WANT_THREADS
pthread_mutex_t mutex;
-#ifdef IS_DARWIN
pthread_mutex_t pidmutex;
- unsigned long pid;
-#endif
#endif
+ unsigned long pid;
friend class PythonThreadIn;
friend class PythonThreadOut;
@@ -177,8 +174,8 @@ const string lastError(PythonRuntime* py) {
PyObject* trace = NULL;
PyErr_Fetch(&type, &val, &trace);
if (type != NULL && val != NULL) {
- PyObject* stype = PyObject_Str(type);
- PyObject* sval = PyObject_Str(val);
+ PyObject* stype = PyObject_Repr(type);
+ PyObject* sval = PyObject_Repr(val);
string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
pyDecRef(stype, py);
pyDecRef(sval, py);
@@ -220,11 +217,10 @@ private:
class PythonThreadIn {
public:
PythonThreadIn(PythonRuntime* py) : py(py) {
-#ifdef WANT_THREADS
-#ifdef IS_DARWIN
// Reinitialize Python thread support after a fork
const unsigned long pid = processId();
+#ifdef WANT_THREADS
if (pid != py->pid) {
pthread_mutex_lock(&py->pidmutex);
if (pid != py->pid) {
@@ -236,16 +232,26 @@ public:
}
pthread_mutex_unlock(&py->pidmutex);
}
-#endif
// Acquire the Python GIL
//debug("python::gil::ensure");
gstate = PyGILState_Ensure();
//debug("python::gil::ensured");
+#else
+ if (pid != py->pid) {
+ debug("python::afterfork");
+ PyOS_AfterFork();
+ debug("python::afterforked");
+ py->pid = pid;
+ }
#endif
}
~PythonThreadIn() {
+ // Run Python cyclic reference garbage collector
+ //const size_t c = PyGC_Collect();
+ //debug(c, "python::gc::collect::c");
+
#ifdef WANT_THREADS
// Release the Python GIL
//debug("python::gil::release");
@@ -520,7 +526,6 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
/**
* Convert a python tuple to a list of values.
*/
-
const list<value> pyTupleToValuesHelper(PyObject* o, const size_t i, const size_t size, PythonRuntime* py) {
if (i == size)
return list<value>();
@@ -546,6 +551,15 @@ struct pyCallable {
pyCallable(const pyCallable& c) : func(c.func), py(c.py), owner(false) {
}
+ const pyCallable& operator=(const pyCallable& c) {
+ if(this == &c)
+ return *this;
+ func = c.func;
+ py = c.py;
+ owner = false;
+ return *this;
+ }
+
~pyCallable() {
if (!owner)
return;
@@ -554,8 +568,7 @@ struct pyCallable {
const value operator()(const list<value>& args) const {
PythonThreadIn pyin(py);
- {
- // Temp
+ if (debug_islogging()) {
PyObject* rfunc = PyObject_Repr(func);
char* s = NULL;
Py_ssize_t l = 0;
@@ -564,8 +577,7 @@ struct pyCallable {
pyDecRef(rfunc, py);
}
PyObject* pyargs = valuesToPyTuple(args, py);
- {
- // Temp
+ if (debug_islogging()) {
PyObject* rargs = PyObject_Repr(pyargs);
char* s = NULL;
Py_ssize_t l = 0;
@@ -573,9 +585,11 @@ struct pyCallable {
debug(string(s, l), "python::operator()::args");
pyDecRef(rargs, py);
}
+
PyObject* result = PyObject_CallObject(func, pyargs);
- const value v = pyObjectToValue(result, py);
pyDecRef(pyargs, py);
+
+ const value v = pyObjectToValue(result, py);
pyDecRef(result, py);
return v;
}
@@ -605,6 +619,8 @@ const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
return value((double)PyFloat_AsDouble(o));
if (PyTuple_Check(o))
return pyTupleToValues(o, py);
+ if (PyObject_TypeCheck(o, &pyLambda_type))
+ return *(((pyLambda*)o)->func);
if (PyCallable_Check(o))
return lambda<value(const list<value>&)>(pyCallable(o, py));
return value();
@@ -646,10 +662,14 @@ const failable<value> evalScript(const value& expr, PyObject* script, PythonRunt
// Call the function
PyObject* result = PyObject_CallObject(func, args);
+ if (result == NULL) {
+ const string msg = lastError(&py);
+ pyDecRef(func, &py);
+ pyDecRef(args, &py);
+ return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + msg);
+ }
pyDecRef(func, &py);
pyDecRef(args, &py);
- if (result == NULL)
- return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastError(&py));
// Convert python result to a value
const value v = pyObjectToValue(result, &py);
@@ -680,10 +700,19 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError(&py));
PyObject* mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
if (mod == NULL) {
+ const string msg = lastError(&py);
pyDecRef(code, &py);
- return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + lastError(&py));
+ return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + msg);
}
- return mod;
+ pyDecRef(code, &py);
+ pyDecRef(mod, &py);
+
+ // Lookup the loaded module
+ PyObject *lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ if (lmod != NULL)
+ return lmod;
+
+ return mkfailure<PyObject*>(string("Couldn't lookup module: ") + path);
}
/**
diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp
index bc275f27c7..29a66cc2e7 100644
--- a/sca-cpp/trunk/modules/python/python-test.cpp
+++ b/sca-cpp/trunk/modules/python/python-test.cpp
@@ -42,7 +42,7 @@ bool testEvalExpr() {
PythonRuntime py;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script1", "script1.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -54,6 +54,29 @@ bool testEvalExpr() {
return true;
}
+const string testPythonMap =
+ "def addmap(x, y):\n"
+ " return tuple(map(lambda i: i + y, x))\n";
+
+bool testEvalList() {
+ gc_scoped_pool pool;
+ PythonRuntime py;
+
+ istringstream is(testPythonMap);
+ failable<PyObject*> script = readScript("script2", "script2.py", is, py);
+ assert(hasContent(script));
+
+ const value exp = mklist<value>("addmap", mklist<value>(1, 2, 3), 1);
+ const failable<value> r = evalScript(exp, content(script), py);
+ assert(hasContent(r));
+ assert(car<value>(content(r)) == value(2));
+ assert(cadr<value>(content(r)) == value(3));
+ assert(caddr<value>(content(r)) == value(4));
+
+ releaseScript(content(script), py);
+ return true;
+}
+
const value mult(const list<value>& args) {
const double x = car(args);
const double y = cadr(args);
@@ -104,7 +127,7 @@ struct testEvalReadAdd {
}
const bool operator()() const {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script3", "script3.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -139,7 +162,7 @@ bool testEvalPerf() {
cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script4", "script4.py", is, py);
assert(hasContent(script));
const lambda<bool()> el = lambda<bool()>(testEvalAdd(content(script), py));
@@ -158,7 +181,7 @@ struct testReadEvalAddLoop {
const bool operator()() const {
for (int i = 0; i < 100; i++) {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script6", "script6.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -247,7 +270,7 @@ bool testThreads() {
cout << "Python eval + read thread test " << time(elr, 1, 1) / 10000.0 << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script7", "script7.py", is, py);
assert(hasContent(script));
const lambda<bool()> el = lambda<bool()>(testEvalThreads(w, max, content(script), py));
@@ -263,9 +286,13 @@ bool testThreads() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::python::testEvalExpr();
+ tuscany::python::testEvalList();
+ tuscany::python::testEvalLambda();
+ tuscany::python::testEvalLambda();
tuscany::python::testEvalLambda();
tuscany::python::testEvalPerf();
#ifdef WANT_THREADS
diff --git a/sca-cpp/trunk/modules/rss/rss-test.cpp b/sca-cpp/trunk/modules/rss/rss-test.cpp
index b30792bfe1..be1dcac574 100644
--- a/sca-cpp/trunk/modules/rss/rss-test.cpp
+++ b/sca-cpp/trunk/modules/rss/rss-test.cpp
@@ -240,6 +240,7 @@ bool testFeed() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::rss::testEntry();
diff --git a/sca-cpp/trunk/modules/scdl/scdl-test.cpp b/sca-cpp/trunk/modules/scdl/scdl-test.cpp
index 94baf930a9..4c10f515df 100644
--- a/sca-cpp/trunk/modules/scdl/scdl-test.cpp
+++ b/sca-cpp/trunk/modules/scdl/scdl-test.cpp
@@ -110,6 +110,7 @@ bool testProperties() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::scdl::testComposite();
diff --git a/sca-cpp/trunk/modules/scheme/scheme-test.cpp b/sca-cpp/trunk/modules/scheme/scheme-test.cpp
index dd97bc358d..5b69b8e588 100644
--- a/sca-cpp/trunk/modules/scheme/scheme-test.cpp
+++ b/sca-cpp/trunk/modules/scheme/scheme-test.cpp
@@ -225,6 +225,7 @@ bool testEvalGC() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::scheme::testEnv();
diff --git a/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp b/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp
index ce5ebfec6f..9907650316 100644
--- a/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp
+++ b/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp
@@ -50,7 +50,7 @@ const list<value> mkfruit(const string& name, const string& code, const string&
mklist<value>("name", name) + mklist<value>("currencyCode", code) + mklist<value>("currencySymbol", symbol) + mklist<value>("price", price);
}
-const failable<value> items(const lambda<value(const list<value>&)> converter, const lambda<value(const list<value>&)> currencyCode) {
+const failable<value> items(const lambda<value(const list<value>&)>& converter, const lambda<value(const list<value>&)>& currencyCode) {
const string currency(currencyCode(list<value>()));
const string symbol(converter(mklist<value>("symbol", currency)));
const lambda<value(const value&)> conv(convert(converter, currency));
diff --git a/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp b/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp
index 4b5dc8db6b..2771d7cd9c 100644
--- a/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp
+++ b/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp
@@ -38,7 +38,7 @@ const string cartId("1234");
* Get the shopping cart from the cache. Return an empty
* cart if not found.
*/
-const list<value> getcart(const value& id, const lambda<value(const list<value>&)> cache) {
+const list<value> getcart(const value& id, const lambda<value(const list<value>&)>& cache) {
const value cart = cache(mklist<value>("get", mklist<value>(id)));
cerr << "cart value: " << cart << "\n";
const failable<value> fcart = cart;
@@ -53,7 +53,7 @@ const list<value> getcart(const value& id, const lambda<value(const list<value>&
/**
* Post a new item to the cart. Create a new cart if necessary.
*/
-const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)> cache) {
+const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)>& cache) {
const value id(mkuuid());
const list<value> newItem(mklist<value>("entry", cadr<value>(car<value>(item)), mklist<value>("id", id), cadddr<value>(car<value>(item))));
const list<value> cart(cons<value>(newItem, getcart(cartId, cache)));
@@ -75,7 +75,7 @@ const value find(const value& id, const list<value>& cart) {
/**
* Return items from the cart.
*/
-const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)> cache) {
+const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)>& cache) {
if (isNil(id))
return value(mklist<value>(append(mklist<value>("feed", mklist<value>("title", string("Your Cart")), mklist<value>("id", cartId)), getcart(cartId, cache))));
return find(car(id), getcart(cartId, cache));
@@ -84,7 +84,7 @@ const failable<value> get(const list<value>& id, const lambda<value(const list<v
/**
* Delete items from the cart.
*/
-const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)> cache) {
+const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)>& cache) {
if (isNil(id))
return cache(mklist<value>("delete", mklist<value>(cartId)));
return value(true);
@@ -109,7 +109,7 @@ const double sum(const list<value>& items) {
/**
* Return the total price of the items in the cart.
*/
-const failable<value> total(const lambda<value(const list<value>&)> cache) {
+const failable<value> total(const lambda<value(const list<value>&)>& cache) {
const list<value> cart(getcart(cartId, cache));
return value(sum(cart));
}