summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/server
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-01-02 10:27:26 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-01-02 10:27:26 +0000
commit95fa76f5f3208d913320c13a05171ecdcd7134c2 (patch)
tree872e101cd2fb1505baf313940e48c6b615fd6725 /sca-cpp/trunk/modules/server
parent1d04916fda43146fb62488c20ba03b7b3006c8e9 (diff)
Performance improvements when running both in multi-threaded and pre-forked HTTPD. Changed memory management to use Apache APR pools instead of ref counting pointers as it's much faster and easier to integrate with the Python and Ruby interpreters. Changed to use simple pool-based string and stream implementations instead of the STL ones, which cause a lots of mutex locks in a multi-threaded environment. Added build options to compile with threading and profiling.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@895165 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/modules/server/client-test.cpp181
-rw-r--r--sca-cpp/trunk/modules/server/impl-test.cpp20
-rw-r--r--sca-cpp/trunk/modules/server/mod-cpp.hpp13
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.cpp126
-rw-r--r--sca-cpp/trunk/modules/server/mod-scm.hpp20
-rw-r--r--sca-cpp/trunk/modules/server/mod-wiring.cpp81
6 files changed, 255 insertions, 186 deletions
diff --git a/sca-cpp/trunk/modules/server/client-test.cpp b/sca-cpp/trunk/modules/server/client-test.cpp
index 496d67f59c..2728cfc6d5 100644
--- a/sca-cpp/trunk/modules/server/client-test.cpp
+++ b/sca-cpp/trunk/modules/server/client-test.cpp
@@ -23,11 +23,12 @@
* Test HTTP client functions.
*/
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <assert.h>
-#include <iostream>
-#include <sstream>
-#include <string>
-#include "slist.hpp"
+#include "stream.hpp"
+#include "string.hpp"
#include "parallel.hpp"
#include "perf.hpp"
#include "../http/curl.hpp"
@@ -35,11 +36,7 @@
namespace tuscany {
namespace server {
-const bool contains(const std::string& str, const std::string& pattern) {
- return str.find(pattern) != str.npos;
-}
-
-std::ostringstream* curlWriter(const std::string& s, std::ostringstream* os) {
+ostream* curlWriter(const string& s, ostream* os) {
(*os) << s;
return os;
}
@@ -47,16 +44,16 @@ std::ostringstream* curlWriter(const std::string& s, std::ostringstream* os) {
const bool testGet() {
http::CURLSession ch;
{
- std::ostringstream os;
- const failable<list<std::ostringstream*>, std::string> r = http::get<std::ostringstream*>(curlWriter, &os, "http://localhost:8090", ch);
+ ostringstream os;
+ const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, "http://localhost:8090", ch);
assert(hasContent(r));
- assert(contains(os.str(), "HTTP/1.1 200 OK"));
- assert(contains(os.str(), "It works"));
+ assert(contains(str(os), "HTTP/1.1 200 OK"));
+ assert(contains(str(os), "It works"));
}
{
- const failable<value, std::string> r = http::get("http://localhost:8090", ch);
+ const failable<value> r = http::getcontent("http://localhost:8090", ch);
assert(hasContent(r));
- assert(contains(content(r), "It works"));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
}
return true;
}
@@ -66,9 +63,9 @@ struct getLoop {
getLoop(http::CURLSession& ch) : ch(ch) {
}
const bool operator()() const {
- const failable<value, std::string> r = get("http://localhost:8090", ch);
+ const failable<value> r = http::getcontent("http://localhost:8090", ch);
assert(hasContent(r));
- assert(contains(content(r), "It works"));
+ assert(contains(car(reverse(list<value>(content(r)))), "It works"));
return true;
}
};
@@ -76,14 +73,14 @@ struct getLoop {
const bool testGetPerf() {
http::CURLSession ch;
const lambda<bool()> gl = getLoop(ch);
- std::cout << "Static GET test " << time(gl, 5, 200) << " ms" << std::endl;
+ cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
return true;
}
const bool testEval() {
http::CURLSession ch;
- const value val = content(http::evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch));
- assert(val == std::string("Hello"));
+ const value val = content(http::evalExpr(mklist<value>(string("echo"), string("Hello")), "http://localhost:8090/test", ch));
+ assert(val == string("Hello"));
return true;
}
@@ -92,13 +89,13 @@ struct evalLoop {
evalLoop(http::CURLSession& ch) : ch(ch) {
}
const bool operator()() const {
- const value val = content(http::evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch));
- assert(val == std::string("Hello"));
+ const value val = content(http::evalExpr(mklist<value>(string("echo"), string("Hello")), "http://localhost:8090/test", ch));
+ assert(val == string("Hello"));
return true;
}
};
-const value blob(std::string(3000, 'A'));
+const value blob(string(3000, 'A'));
const list<value> blobs = mklist(blob, blob, blob, blob, blob);
struct blobEvalLoop {
@@ -106,7 +103,7 @@ struct blobEvalLoop {
blobEvalLoop(http::CURLSession& ch) : ch(ch) {
}
const bool operator()() const {
- const value val = content(http::evalExpr(mklist<value>(std::string("echo"), blobs), "http://localhost:8090/test", ch));
+ const value val = content(http::evalExpr(mklist<value>(string("echo"), blobs), "http://localhost:8090/test", ch));
assert(val == blobs);
return true;
}
@@ -115,19 +112,19 @@ struct blobEvalLoop {
const bool testEvalPerf() {
http::CURLSession ch;
const lambda<bool()> el = evalLoop(ch);
- std::cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << std::endl;
+ cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl;
const lambda<bool()> bel = blobEvalLoop(ch);
- std::cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << std::endl;
+ cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << endl;
return true;
}
bool testPost() {
const list<value> i = list<value>()
- << (list<value>() << "name" << std::string("Apple"))
- << (list<value>() << "price" << std::string("$2.99"));
- const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
http::CURLSession ch;
- const failable<value, std::string> id = http::post(a, "http://localhost:8090/test", ch);
+ const failable<value> id = http::post(a, "http://localhost:8090/test", ch);
assert(hasContent(id));
return true;
}
@@ -138,7 +135,7 @@ struct postLoop {
postLoop(const value& val, http::CURLSession& ch) : val(val), ch(ch) {
}
const bool operator()() const {
- const failable<value, std::string> id = http::post(val, "http://localhost:8090/test", ch);
+ const failable<value> id = http::post(val, "http://localhost:8090/test", ch);
assert(hasContent(id));
return true;
}
@@ -148,28 +145,30 @@ const bool testPostPerf() {
http::CURLSession ch;
{
const list<value> i = list<value>()
- << (list<value>() << "name" << std::string("Apple"))
- << (list<value>() << "price" << std::string("$2.99"));
- const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> val = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
const lambda<bool()> pl = postLoop(val, ch);
- std::cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << std::endl;
+ cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << endl;
}
{
const list<value> i = list<value>()
- << (list<value>() << "name" << std::string("Apple"))
- << (list<value>() << "blob1" << blob)
- << (list<value>() << "blob2" << blob)
- << (list<value>() << "blob3" << blob)
- << (list<value>() << "blob4" << blob)
- << (list<value>() << "blob5" << blob)
- << (list<value>() << "price" << std::string("$2.99"));
- const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "blob1" + blob)
+ + (list<value>() + "blob2" + blob)
+ + (list<value>() + "blob3" + blob)
+ + (list<value>() + "blob4" + blob)
+ + (list<value>() + "blob5" + blob)
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> val = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
const lambda<bool()> pl = postLoop(val, ch);
- std::cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << std::endl;
+ cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl;
}
return true;
}
+#ifdef _REENTRANT
+
const bool postThread(const int count, const value& val) {
http::CURLSession ch;
const lambda<bool()> pl = postLoop(val, ch);
@@ -194,7 +193,7 @@ struct postThreadLoop {
const lambda<bool()> l;
const int threads;
const gc_ptr<worker> w;
- postThreadLoop(const lambda<bool()>& l, const int threads) : l(l), threads(threads), w(new worker(threads)) {
+ postThreadLoop(const lambda<bool()>& l, const int threads) : l(l), threads(threads), w(new (gc_new<worker>()) worker(threads)) {
}
const bool operator()() const {
list<future<bool> > r = startPost(*w, threads, l);
@@ -208,23 +207,83 @@ const bool testPostThreadPerf() {
const int threads = 10;
const list<value> i = list<value>()
- << (list<value>() << "name" << std::string("Apple"))
- << (list<value>() << "price" << std::string("$2.99"));
- const value val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const value val = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
const lambda<bool()> pl= curry(lambda<bool(const int, const value)>(postThread), count, val);
const lambda<bool()> ptl = postThreadLoop(pl, threads);
double t = time(ptl, 0, 1) / (threads * count);
- std::cout << "ATOMPub POST thread test " << t << " ms" << std::endl;
+ cout << "ATOMPub POST thread test " << t << " ms" << endl;
return true;
}
+#else
+
+const bool postProc(const int count, const value& val) {
+ http::CURLSession ch;
+ const lambda<bool()> pl = postLoop(val, ch);
+ time(pl, 0, count);
+ return true;
+}
+
+const list<pid_t> startPost(const int procs, const lambda<bool()>& l) {
+ if (procs == 0)
+ return list<pid_t>();
+ pid_t pid = fork();
+ if (pid == 0) {
+ assert(l() == true);
+ exit(0);
+ }
+ return cons(pid, startPost(procs - 1, l));
+}
+
+const bool checkPost(const list<pid_t>& r) {
+ if (isNil(r))
+ return true;
+ int status;
+ waitpid(car(r), &status, 0);
+ assert(status == 0);
+ return checkPost(cdr(r));
+}
+
+struct postForkLoop {
+ const lambda<bool()> l;
+ const int procs;
+ postForkLoop(const lambda<bool()>& l, const int procs) : l(l), procs(procs) {
+ }
+ const bool operator()() const {
+ list<pid_t> r = startPost(procs, l);
+ checkPost(r);
+ return true;
+ }
+};
+
+const bool testPostForkPerf() {
+ const int count = 50;
+ const int procs = 10;
+
+ const list<value> i = list<value>()
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const value val = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+
+ const lambda<bool()> pl= curry(lambda<bool(const int, const value)>(postProc), count, val);
+ const lambda<bool()> ptl = postForkLoop(pl, procs);
+ double t = time(ptl, 0, 1) / (procs * count);
+ cout << "ATOMPub POST fork test " << t << " ms" << endl;
+
+ return true;
+}
+
+#endif
+
const bool testPut() {
const list<value> i = list<value>()
- << (list<value>() << "name" << std::string("Apple"))
- << (list<value>() << "price" << std::string("$2.99"));
- const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+ + (list<value>() + "name" + string("Apple"))
+ + (list<value>() + "price" + string("$2.99"));
+ const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
http::CURLSession ch;
value rc = content(http::put(a, "http://localhost:8090/test/111", ch));
assert(rc == value(true));
@@ -240,8 +299,8 @@ const bool testDel() {
const bool testEvalCpp() {
http::CURLSession ch;
- const value val = content(http::evalExpr(mklist<value>(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch));
- assert(val == std::string("hello world"));
+ const value val = content(http::evalExpr(mklist<value>(string("hello"), string("world")), "http://localhost:8090/cpp", ch));
+ assert(val == string("hello world"));
return true;
}
@@ -250,8 +309,8 @@ struct evalCppLoop {
evalCppLoop(http::CURLSession& ch) : ch(ch) {
}
const bool operator()() const {
- const value val = content(http::evalExpr(mklist<value>(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch));
- assert(val == std::string("hello world"));
+ const value val = content(http::evalExpr(mklist<value>(string("hello"), string("world")), "http://localhost:8090/cpp", ch));
+ assert(val == string("hello world"));
return true;
}
};
@@ -259,7 +318,7 @@ struct evalCppLoop {
const bool testEvalCppPerf() {
http::CURLSession ch;
const lambda<bool()> el = evalCppLoop(ch);
- std::cout << "JSON-RPC C++ eval test " << time(el, 5, 200) << " ms" << std::endl;
+ cout << "JSON-RPC C++ eval test " << time(el, 5, 200) << " ms" << endl;
return true;
}
@@ -267,13 +326,17 @@ const bool testEvalCppPerf() {
}
int main() {
- std::cout << "Testing..." << std::endl;
+ tuscany::cout << "Testing..." << tuscany::endl;
tuscany::server::testGet();
tuscany::server::testGetPerf();
tuscany::server::testPost();
tuscany::server::testPostPerf();
+#ifdef _REENTRANT
tuscany::server::testPostThreadPerf();
+#else
+ tuscany::server::testPostForkPerf();
+#endif
tuscany::server::testEval();
tuscany::server::testEvalPerf();
tuscany::server::testPut();
@@ -281,7 +344,7 @@ int main() {
tuscany::server::testEvalCpp();
tuscany::server::testEvalCppPerf();
- std::cout << "OK" << std::endl;
+ tuscany::cout << "OK" << tuscany::endl;
return 0;
}
diff --git a/sca-cpp/trunk/modules/server/impl-test.cpp b/sca-cpp/trunk/modules/server/impl-test.cpp
index 171a78f2d5..d2a45c2fa9 100644
--- a/sca-cpp/trunk/modules/server/impl-test.cpp
+++ b/sca-cpp/trunk/modules/server/impl-test.cpp
@@ -23,7 +23,7 @@
* Test component implementation.
*/
-#include <string>
+#include "string.hpp"
#include "function.hpp"
#include "list.hpp"
@@ -34,24 +34,24 @@
namespace tuscany {
namespace server {
-const failable<value, std::string> get(unused const list<value>& params) {
- return value(std::string("Hey"));
+const failable<value> get(unused const list<value>& params) {
+ return value(string("Hey"));
}
-const failable<value, std::string> post(unused const list<value>& params) {
- return value(std::string("1234"));
+const failable<value> post(unused const list<value>& params) {
+ return value(string("1234"));
}
-const failable<value, std::string> put(unused const list<value>& params) {
+const failable<value> put(unused const list<value>& params) {
return value(true);
}
-const failable<value, std::string> del(unused const list<value>& params) {
+const failable<value> del(unused const list<value>& params) {
return value(true);
}
-const failable<value, std::string> hello(const list<value>& params) {
- return value(std::string("hello ") + std::string(car(params)));
+const failable<value> hello(const list<value>& params) {
+ return value(string("hello ") + string(car(params)));
}
}
@@ -71,7 +71,7 @@ const tuscany::value eval(const tuscany::list<tuscany::value>& params) {
return tuscany::server::del(cdr(params));
if (func == "hello")
return tuscany::server::hello(cdr(params));
- return tuscany::mkfailure<tuscany::value, std::string>(std::string("Function not supported: ") + std::string(func));
+ return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func);
}
}
diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp
index 664e9d2e41..2cf2e540d6 100644
--- a/sca-cpp/trunk/modules/server/mod-cpp.hpp
+++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp
@@ -27,9 +27,8 @@
* component implementations.
*/
-#include <string>
-#include <iostream>
-#include <fstream>
+#include "string.hpp"
+#include "stream.hpp"
#include "function.hpp"
#include "list.hpp"
@@ -65,12 +64,12 @@ struct evalImplementation {
/**
* Read a C++ component implementation.
*/
-const failable<lambda<value(const list<value>&)>, std::string> readImplementation(const std::string path, const list<value>& px) {
- const failable<lib, std::string> ilib(dynlib(path + dynlibExt));
+const failable<lambda<value(const list<value>&)> > readImplementation(const string& path, const list<value>& px) {
+ const failable<lib> ilib(dynlib(path + dynlibExt));
if (!hasContent(ilib))
- return mkfailure<lambda<value(const list<value>&)>, std::string>(reason(ilib));
+ return mkfailure<lambda<value(const list<value>&)> >(reason(ilib));
- const failable<lambda<value(const list<value>&)>, std::string> impl(dynlambda<value(const list<value>&)>("eval", content(ilib)));
+ const failable<lambda<value(const list<value>&)> > impl(dynlambda<value(const list<value>&)>("eval", content(ilib)));
if (!hasContent(impl))
return impl;
return lambda<value(const list<value>&)>(evalImplementation(content(ilib), content(impl), px));
diff --git a/sca-cpp/trunk/modules/server/mod-eval.cpp b/sca-cpp/trunk/modules/server/mod-eval.cpp
index d8354c6a58..8e8870dd52 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.cpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.cpp
@@ -23,15 +23,11 @@
* HTTPD module used to eval component implementations.
*/
-#include <string>
-#include <iostream>
-#include <sstream>
-#include <fstream>
-
+#include "string.hpp"
+#include "stream.hpp"
#include "function.hpp"
#include "list.hpp"
#include "tree.hpp"
-#include "slist.hpp"
#include "value.hpp"
#include "element.hpp"
#include "monad.hpp"
@@ -58,9 +54,10 @@ class ServerConf {
public:
ServerConf(server_rec* s) : s(s), home(""), wiringServerName("") {
}
+
const server_rec* s;
- std::string home;
- std::string wiringServerName;
+ string home;
+ string wiringServerName;
};
/**
@@ -71,8 +68,8 @@ public:
DirConf(char* dirspec) : dirspec(dirspec), contributionPath(""), compositeName("") {
}
const char* dirspec;
- std::string contributionPath;
- std::string compositeName;
+ string contributionPath;
+ string compositeName;
list<value> implementations;
};
@@ -80,16 +77,16 @@ public:
* Convert a result represented as a content + failure pair to a
* failable monad.
*/
-const failable<value, std::string> failableResult(const list<value>& v) {
+const failable<value> failableResult(const list<value>& v) {
if (isNil(cdr(v)))
return car(v);
- return mkfailure<value, std::string>(cadr(v));
+ return mkfailure<value>(string(cadr(v)));
}
/**
* Handle an HTTP GET.
*/
-const failable<int, std::string> get(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>& impl) {
debug(r->uri, "modeval::get::uri");
// Inspect the query string
@@ -102,12 +99,12 @@ const failable<int, std::string> get(request_rec* r, const lambda<value(const li
// Extract the request id, method and params
const value id = cadr(ia);
- const value func = std::string(cadr(ma)).c_str();
+ const value func = c_str(string(cadr(ma)));
// Apply the requested function
- const failable<value, std::string> val = failableResult(impl(cons(func, httpd::queryParams(args))));
+ const failable<value> val = failableResult(impl(cons(func, httpd::queryParams(args))));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
// Return JSON result
json::JSONContext cx;
@@ -115,58 +112,58 @@ const failable<int, std::string> get(request_rec* r, const lambda<value(const li
}
// Evaluate an ATOM GET request and return an ATOM feed
- const list<value> path(httpd::path(r->uri));
+ const list<value> path(httpd::pathValues(r->uri));
if (isNil(cddr(path))) {
- const failable<value, std::string> val = failableResult(impl(cons<value>("getall", list<value>())));
+ const failable<value> val = failableResult(impl(cons<value>("getall", list<value>())));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(content(val))), "application/atom+xml;type=feed", r);
}
// Evaluate an ATOM GET and return an ATOM entry
- const failable<value, std::string> val = failableResult(impl(cons<value>("get", mklist<value>(caddr(path)))));
+ const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(caddr(path)))));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(content(val))), "application/atom+xml;type=entry", r);
}
/**
* Handle an HTTP POST.
*/
-const failable<int, std::string> post(request_rec* r, const lambda<value(const list<value>&)>& impl) {
- const list<std::string> ls = httpd::read(r);
+const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ const list<string> ls = httpd::read(r);
debug(r->uri, "modeval::post::url");
debug(ls, "modeval::post::input");
// Evaluate a JSON-RPC request and return a JSON result
- const std::string ct = httpd::contentType(r);
- if (ct.find("application/json-rpc") != std::string::npos || ct.find("text/plain") != std::string::npos) {
+ const string ct = httpd::contentType(r);
+ if (contains(ct, "application/json-rpc") || contains(ct, "text/plain")) {
json::JSONContext cx;
const list<value> json = elementsToValues(content(json::readJSON(ls, cx)));
const list<list<value> > args = httpd::postArgs(json);
// Extract the request id, method and params
const value id = cadr(assoc(value("id"), args));
- const value func = std::string(cadr(assoc(value("method"), args))).c_str();
+ const value func = c_str(cadr(assoc(value("method"), args)));
const list<value> params = (list<value>)cadr(assoc(value("params"), args));
// Evaluate the request expression
- const failable<value, std::string> val = failableResult(impl(cons<value>(func, params)));
+ const failable<value> val = failableResult(impl(cons<value>(func, params)));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
// Return JSON result
return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc", r);
}
// Evaluate an ATOM POST request and return the created resource location
- if (ct.find("application/atom+xml") != std::string::npos) {
+ if (contains(ct, "application/atom+xml")) {
// Evaluate the request expression
const value entry = atom::entryValue(content(atom::readEntry(ls)));
- const failable<value, std::string> val = failableResult(impl(cons<value>("post", mklist<value>(entry))));
+ const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(entry))));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
// Return the created resource location
apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, httpd::url(content(val), r)));
@@ -180,17 +177,17 @@ const failable<int, std::string> post(request_rec* r, const lambda<value(const l
/**
* Handle an HTTP PUT.
*/
-const failable<int, std::string> put(request_rec* r, const lambda<value(const list<value>&)>& impl) {
- const list<std::string> ls = httpd::read(r);
+const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+ const list<string> ls = httpd::read(r);
debug(r->uri, "modeval::put::url");
debug(ls, "modeval::put::input");
// Evaluate an ATOM PUT request
- const list<value> path(httpd::path(r->uri));
+ const list<value> path(httpd::pathValues(r->uri));
const value entry = atom::entryValue(content(atom::readEntry(ls)));
- const failable<value, std::string> val = failableResult(impl(cons<value>("put", mklist<value>(caddr(path), entry))));
+ const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(caddr(path), entry))));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
if (val == value(false))
return HTTP_NOT_FOUND;
return OK;
@@ -199,14 +196,14 @@ const failable<int, std::string> put(request_rec* r, const lambda<value(const li
/**
* Handle an HTTP DELETE.
*/
-const failable<int, std::string> del(request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> del(request_rec* r, const lambda<value(const list<value>&)>& impl) {
debug(r->uri, "modeval::delete::url");
// Evaluate an ATOM delete request
- const list<value> path(httpd::path(r->uri));
- const failable<value, std::string> val = failableResult(impl(cons<value>("delete", mklist<value>(caddr(path)))));
+ const list<value> path(httpd::pathValues(r->uri));
+ const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(caddr(path)))));
if (!hasContent(val))
- return mkfailure<int, std::string>(reason(val));
+ return mkfailure<int>(reason(val));
if (val == value(false))
return HTTP_NOT_FOUND;
return OK;
@@ -216,6 +213,7 @@ const failable<int, std::string> del(request_rec* r, const lambda<value(const li
* Translate a component request.
*/
int translate(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
if (strncmp(r->uri, "/components/", 12) != 0)
return DECLINED;
r->handler = "mod_tuscany_eval";
@@ -226,6 +224,7 @@ int translate(request_rec *r) {
* HTTP request handler.
*/
int handler(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
if(strcmp(r->handler, "mod_tuscany_eval"))
return DECLINED;
httpdDebugRequest(r, "modeval::handler::input");
@@ -237,7 +236,7 @@ int handler(request_rec *r) {
// Get the component implementation lambda
DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_eval);
- const list<value> path(httpd::path(r->uri));
+ const list<value> path(httpd::pathValues(r->uri));
const list<value> impl(assoctree<value>(cadr(path), dc.implementations));
if (isNil(impl))
return HTTP_NOT_FOUND;
@@ -260,11 +259,11 @@ int handler(request_rec *r) {
/**
* Convert a list of component references to a list of HTTP proxy lambdas.
*/
-const value mkproxy(const value& ref, const std::string& base) {
- return lambda<value(const list<value>&)>(http::proxy(base + std::string(scdl::name(ref))));
+const value mkproxy(const value& ref, const string& base) {
+ return lambda<value(const list<value>&)>(http::proxy(base + string(scdl::name(ref))));
}
-const list<value> proxies(const list<value>& refs, const std::string& base) {
+const list<value> proxies(const list<value>& refs, const string& base) {
if (isNil(refs))
return refs;
return cons(mkproxy(car(refs), base), proxies(cdr(refs), base));
@@ -274,31 +273,31 @@ const list<value> proxies(const list<value>& refs, const std::string& base) {
* Return a configured component implementation.
* For now only Scheme and C++ implementations are supported.
*/
-const failable<lambda<value(const list<value>&)>, std::string> readImplementation(const std::string& itype, const std::string& path, const list<value>& px) {
- if (itype.find(".scheme") != std::string::npos)
+const failable<lambda<value(const list<value>&)> > readImplementation(const string& itype, const string& path, const list<value>& px) {
+ if (contains(itype, ".scheme"))
return scm::readImplementation(path, px);
- if (itype.find(".cpp") != std::string::npos)
+ if (contains(itype, ".cpp"))
return cpp::readImplementation(path, px);
- return mkfailure<lambda<value(const list<value>&)>, std::string>("Unsupported implementation type: " + itype);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
}
const value confImplementation(DirConf& dc, ServerConf& sc, server_rec& server, const value& comp) {
const value impl = scdl::implementation(comp);
- const std::string path = dc.contributionPath + std::string(scdl::uri(impl));
+ const string path = dc.contributionPath + string(scdl::uri(impl));
// Convert component references to configured proxy lambdas
- std::ostringstream base;
+ ostringstream base;
if (sc.wiringServerName == "")
base << (server.server_scheme == NULL? "http" : server.server_scheme)
<< "://" << (server.server_hostname == NULL? "localhost" : server.server_hostname)
<< ":" << (server.port == 0? 80 : server.port)
- << "/references/" << std::string(scdl::name(comp)) << "/";
+ << "/references/" << string(scdl::name(comp)) << "/";
else
- base << sc.wiringServerName << "/references/" << std::string(scdl::name(comp)) << "/";
- const list<value> px(proxies(scdl::references(comp), base.str()));
+ base << sc.wiringServerName << "/references/" << string(scdl::name(comp)) << "/";
+ const list<value> px(proxies(scdl::references(comp), str(base)));
// Read and configure the implementation
- const failable<lambda<value(const list<value>&)>, std::string> cimpl(readImplementation(elementName(impl), path, px));
+ const failable<lambda<value(const list<value>&)> > cimpl(readImplementation(elementName(impl), path, px));
if (!hasContent(cimpl))
return reason(cimpl);
return content(cimpl);
@@ -320,10 +319,10 @@ const list<value> componentToImplementationTree(DirConf& dc, ServerConf& sc, ser
/**
* Read the components declared in a composite.
*/
-const failable<list<value>, std::string> readComponents(const std::string& path) {
- std::ifstream is(path);
- if (is.fail() || is.bad())
- return mkfailure<list<value>, std::string>("Could not read composite: " + path);
+const failable<list<value> > readComponents(const string& path) {
+ ifstream is(path);
+ if (fail(is))
+ return mkfailure<list<value> >(string("Could not read composite: ") + path);
return scdl::components(readXML(streamList(is)));
}
@@ -333,7 +332,7 @@ const failable<list<value>, std::string> readComponents(const std::string& path)
const bool confComponents(DirConf& dc, ServerConf& sc, server_rec& server) {
if (dc.contributionPath == "" || dc.compositeName == "")
return true;
- const failable<list<value>, std::string> comps = readComponents(dc.contributionPath + dc.compositeName);
+ const failable<list<value> > comps = readComponents(dc.contributionPath + dc.compositeName);
if (!hasContent(comps))
return true;
dc.implementations = componentToImplementationTree(dc, sc, server, content(comps));
@@ -345,16 +344,19 @@ const bool confComponents(DirConf& dc, ServerConf& sc, server_rec& server) {
* Configuration commands.
*/
const char *confHome(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.home = arg;
return NULL;
}
const char *confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.wiringServerName = arg;
return NULL;
}
const char *confContribution(cmd_parms *cmd, void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
DirConf& dc = *(DirConf*)c;
dc.contributionPath = arg;
@@ -362,6 +364,7 @@ const char *confContribution(cmd_parms *cmd, void *c, const char *arg) {
return NULL;
}
const char *confComposite(cmd_parms *cmd, void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
DirConf& dc = *(DirConf*)c;
dc.compositeName = arg;
@@ -384,10 +387,11 @@ int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t
return OK;
}
-void childInit(unused apr_pool_t* p, server_rec* svr_rec) {
+void childInit(apr_pool_t* p, server_rec* svr_rec) {
+ gc_scoped_pool pool(p);
ServerConf* c = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_eval);
if(c == NULL) {
- std::cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << std::endl;
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
exit(APEXIT_CHILDFATAL);
}
}
diff --git a/sca-cpp/trunk/modules/server/mod-scm.hpp b/sca-cpp/trunk/modules/server/mod-scm.hpp
index c454c6a216..887b1de968 100644
--- a/sca-cpp/trunk/modules/server/mod-scm.hpp
+++ b/sca-cpp/trunk/modules/server/mod-scm.hpp
@@ -27,10 +27,8 @@
* component implementations.
*/
-#include <string>
-#include <iostream>
-#include <fstream>
-
+#include "string.hpp"
+#include "stream.hpp"
#include "function.hpp"
#include "list.hpp"
#include "value.hpp"
@@ -65,12 +63,12 @@ struct evalImplementation {
const value operator()(const list<value>& params) const {
const value expr = cons<value>(car(params), append(eval::quotedParameters(cdr(params)), px));
debug(expr, "modeval::scm::evalImplementation::input");
- gc_pool pool;
+ gc_pool pool(gc_current_pool());
eval::Env globalEnv = eval::setupEnvironment(pool);
const value val = eval::evalScript(expr, impl, globalEnv, pool);
debug(val, "modeval::scm::evalImplementation::result");
if (isNil(val))
- return mklist<value>(value(), std::string("Could not evaluate expression"));
+ return mklist<value>(value(), string("Could not evaluate expression"));
return mklist<value>(val);
}
};
@@ -78,13 +76,13 @@ struct evalImplementation {
/**
* Read a script component implementation.
*/
-const failable<lambda<value(const list<value>&)>, std::string> readImplementation(const std::string path, const list<value>& px) {
- std::ifstream is(path.c_str(), std::ios_base::in);
- if (is.fail() || is.bad())
- return mkfailure<lambda<value(const list<value>&)>, std::string>("Could not read implementation: " + path);
+const failable<lambda<value(const list<value>&)> > readImplementation(const string& path, const list<value>& px) {
+ ifstream is(path);
+ if (fail(is))
+ return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + path);
const value impl = eval::readScript(is);
if (isNil(impl))
- return mkfailure<lambda<value(const list<value>&)>, std::string>("Could not read implementation: " + path);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + path);
return lambda<value(const list<value>&)>(evalImplementation(impl, px));
}
diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp
index 1bb5d1a687..6b4308edda 100644
--- a/sca-cpp/trunk/modules/server/mod-wiring.cpp
+++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp
@@ -26,13 +26,9 @@
#include <sys/stat.h>
-#include <string>
-#include <iostream>
-#include <sstream>
-#include <fstream>
-
+#include "string.hpp"
+#include "stream.hpp"
#include "list.hpp"
-#include "slist.hpp"
#include "tree.hpp"
#include "value.hpp"
#include "debug.hpp"
@@ -56,8 +52,8 @@ public:
ServerConf(server_rec* s) : s(s), home(""), wiringServerName("") {
}
const server_rec* s;
- std::string home;
- std::string wiringServerName;
+ string home;
+ string wiringServerName;
};
/**
@@ -73,8 +69,8 @@ public:
DirConf(char* dirspec) : dirspec(dirspec), contributionPath(""), compositeName("") {
}
const char* dirspec;
- std::string contributionPath;
- std::string compositeName;
+ string contributionPath;
+ string compositeName;
list<value> references;
list<value> services;
};
@@ -82,8 +78,8 @@ public:
/**
* Returns true if a URI is absolute.
*/
-const bool isAbsolute(const std::string& uri) {
- return uri.find("://") != std::string::npos;
+const bool isAbsolute(const string& uri) {
+ return contains(uri, "://");
}
/**
@@ -96,7 +92,7 @@ int translateReference(request_rec *r) {
// Find the requested component
DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_wiring);
- const list<value> rpath(httpd::path(r->uri));
+ const list<value> rpath(httpd::pathValues(r->uri));
const list<value> comp(assoctree(cadr(rpath), dc.references));
if (isNil(comp))
return HTTP_NOT_FOUND;
@@ -105,26 +101,26 @@ int translateReference(request_rec *r) {
const list<value> ref(assoctree<value>(caddr(rpath), cadr(comp)));
if (isNil(ref))
return HTTP_NOT_FOUND;
- const std::string target(cadr(ref));
+ const string target(cadr(ref));
debug(target, "modwiring::translateReference::target");
// Route to an absolute target URI using mod_proxy or an HTTP client redirect
if (isAbsolute(target)) {
if (useModProxy) {
- r->filename = apr_pstrdup(r->pool, std::string("proxy:" + target).c_str());
+ r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + target));
r->proxyreq = PROXYREQ_REVERSE;
r->handler = "proxy-server";
return OK;
}
r->status = HTTP_MOVED_TEMPORARILY;
- apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, target.c_str()));
+ apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, c_str(target)));
r->handler = "mod_tuscany_wiring";
return OK;
}
// Route to a relative target URI using a local internal redirect
- r->filename = apr_pstrdup(r->pool, std::string("/redirect:/components/" + target).c_str());
+ r->filename = apr_pstrdup(r->pool, c_str(string("/redirect:/components/") + target));
r->handler = "mod_tuscany_wiring";
return OK;
}
@@ -161,7 +157,7 @@ int translateService(request_rec *r) {
// Find the requested component
DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_wiring);
- const list<value> path(httpd::path(r->uri));
+ const list<value> path(httpd::pathValues(r->uri));
const list<value> svc(assocPath(path, dc.services));
if (isNil(svc))
return DECLINED;
@@ -172,9 +168,11 @@ int translateService(request_rec *r) {
debug(target, "modwiring::translateService::target");
// Dispatch to the target component using a local internal redirect
- const std::string redir(std::string("/redirect:/components") + httpd::path(target));
+ const string p(httpd::path(target));
+ debug(p, "modwiring::translateService::path");
+ const string redir(string("/redirect:/components") + httpd::path(target));
debug(redir, "modwiring::translateService::redirect");
- r->filename = apr_pstrdup(r->pool, redir.c_str());
+ r->filename = apr_pstrdup(r->pool, c_str(redir));
r->handler = "mod_tuscany_wiring";
return OK;
}
@@ -184,6 +182,7 @@ int translateService(request_rec *r) {
* to the target component.
*/
int translate(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
if (!strncmp(r->uri, "/components/", 12) != 0)
return DECLINED;
@@ -198,11 +197,11 @@ int translate(request_rec *r) {
/**
* Construct a redirect URI.
*/
-const std::string redirect(const std::string& file, const std::string& pi) {
+const string redirect(const string& file, const string& pi) {
return file + pi;
}
-const std::string redirect(const std::string& file, const std::string& pi, const std::string& args) {
+const string redirect(const string& file, const string& pi, const string& args) {
return file + pi + "?" + args;
}
@@ -210,6 +209,7 @@ const std::string redirect(const std::string& file, const std::string& pi, const
* HTTP request handler, redirect to a target component.
*/
int handler(request_rec *r) {
+ gc_scoped_pool pool(r->pool);
if(strcmp(r->handler, "mod_tuscany_wiring"))
return DECLINED;
httpdDebugRequest(r, "modwiring::handler::input");
@@ -222,20 +222,20 @@ int handler(request_rec *r) {
debug(r->path_info, "modwiring::handler::path info");
if (r->args == NULL) {
- ap_internal_redirect(apr_pstrdup(r->pool, redirect(r->filename + 10, r->path_info).c_str()), r);
+ ap_internal_redirect(apr_pstrdup(r->pool, c_str(redirect(string(r->filename + 10), string(r->path_info)))), r);
return OK;
}
- ap_internal_redirect(apr_pstrdup(r->pool, redirect(r->filename + 10, r->path_info, r->args).c_str()), r);
+ ap_internal_redirect(apr_pstrdup(r->pool, c_str(redirect(string(r->filename + 10), string(r->path_info), string(r->args)))), r);
return OK;
}
/**
* Read the components declared in a composite.
*/
-const failable<list<value>, std::string> readComponents(const std::string& path) {
- std::ifstream is(path);
- if (is.fail() || is.bad())
- return mkfailure<list<value>, std::string>("Could not read composite: " + path);
+const failable<list<value> > readComponents(const string& path) {
+ ifstream is(path);
+ if (fail(is))
+ return mkfailure<list<value> >(string("Could not read composite: ") + path);
return scdl::components(readXML(streamList(is)));
}
@@ -261,23 +261,23 @@ const list<value> componentReferenceToTargetTree(const list<value>& c) {
* Return a tree of service-URI-path + component-name pairs. Service-URI-paths are
* represented as lists of URI path fragments.
*/
-const list<value> defaultBindingURI(const std::string& cn, const std::string& sn) {
+const list<value> defaultBindingURI(const string& cn, const string& sn) {
return mklist<value>(cn, sn);
}
-const list<value> bindingToComponentAssoc(const std::string& cn, const std::string& sn, const list<value>& b) {
+const list<value> bindingToComponentAssoc(const string& cn, const string& sn, const list<value>& b) {
if (isNil(b))
return b;
const value uri(scdl::uri(car(b)));
if (isNil(uri))
return cons<value>(mklist<value>(defaultBindingURI(cn, sn), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
- return cons<value>(mklist<value>(httpd::path(std::string(uri).c_str()), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
+ return cons<value>(mklist<value>(httpd::pathValues(c_str(string(uri))), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
}
-const list<value> serviceToComponentAssoc(const std::string& cn, const list<value>& s) {
+const list<value> serviceToComponentAssoc(const string& cn, const list<value>& s) {
if (isNil(s))
return s;
- const std::string sn(scdl::name(car(s)));
+ const string sn(scdl::name(car(s)));
const list<value> btoc(bindingToComponentAssoc(cn, sn, scdl::bindings(car(s))));
if (isNil(btoc))
return cons<value>(mklist<value>(defaultBindingURI(cn, sn), cn), serviceToComponentAssoc(cn, cdr(s)));
@@ -300,7 +300,7 @@ const list<value> uriToComponentTree(const list<value>& c) {
const bool confComponents(DirConf& dc) {
if (dc.contributionPath == "" || dc.compositeName == "")
return true;
- const failable<list<value>, std::string> comps = readComponents(dc.contributionPath + dc.compositeName);
+ const failable<list<value> > comps = readComponents(dc.contributionPath + dc.compositeName);
if (!hasContent(comps))
return true;
dc.references = componentReferenceToTargetTree(content(comps));
@@ -314,22 +314,26 @@ const bool confComponents(DirConf& dc) {
* Configuration commands.
*/
const char *confHome(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring);
sc.home = arg;
return NULL;
}
const char *confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring);
sc.wiringServerName = arg;
return NULL;
}
-const char *confContribution(unused cmd_parms *cmd, void *c, const char *arg) {
+const char *confContribution(cmd_parms *cmd, void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
DirConf& dc = *(DirConf*)c;
dc.contributionPath = arg;
confComponents(dc);
return NULL;
}
-const char *confComposite(unused cmd_parms *cmd, void *c, const char *arg) {
+const char *confComposite(cmd_parms *cmd, void *c, const char *arg) {
+ gc_scoped_pool pool(cmd->pool);
DirConf& dc = *(DirConf*)c;
dc.compositeName = arg;
confComponents(dc);
@@ -351,10 +355,11 @@ int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t
return OK;
}
-void childInit(unused apr_pool_t* p, server_rec* svr_rec) {
+void childInit(apr_pool_t* p, server_rec* svr_rec) {
+ gc_scoped_pool pool(p);
ServerConf *conf = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_wiring);
if(conf == NULL) {
- std::cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << std::endl;
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << endl;
exit(APEXIT_CHILDFATAL);
}
}