From 95fa76f5f3208d913320c13a05171ecdcd7134c2 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Sat, 2 Jan 2010 10:27:26 +0000 Subject: 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 --- sca-cpp/trunk/modules/server/client-test.cpp | 181 ++++++++++++++++++--------- sca-cpp/trunk/modules/server/impl-test.cpp | 20 +-- sca-cpp/trunk/modules/server/mod-cpp.hpp | 13 +- sca-cpp/trunk/modules/server/mod-eval.cpp | 126 ++++++++++--------- sca-cpp/trunk/modules/server/mod-scm.hpp | 20 ++- sca-cpp/trunk/modules/server/mod-wiring.cpp | 81 ++++++------ 6 files changed, 255 insertions(+), 186 deletions(-) (limited to 'sca-cpp/trunk/modules/server') 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 +#include +#include #include -#include -#include -#include -#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, std::string> r = http::get(curlWriter, &os, "http://localhost:8090", ch); + ostringstream os; + const failable > r = http::get(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 r = http::get("http://localhost:8090", ch); + const failable r = http::getcontent("http://localhost:8090", ch); assert(hasContent(r)); - assert(contains(content(r), "It works")); + assert(contains(car(reverse(list(content(r)))), "It works")); } return true; } @@ -66,9 +63,9 @@ struct getLoop { getLoop(http::CURLSession& ch) : ch(ch) { } const bool operator()() const { - const failable r = get("http://localhost:8090", ch); + const failable r = http::getcontent("http://localhost:8090", ch); assert(hasContent(r)); - assert(contains(content(r), "It works")); + assert(contains(car(reverse(list(content(r)))), "It works")); return true; } }; @@ -76,14 +73,14 @@ struct getLoop { const bool testGetPerf() { http::CURLSession ch; const lambda 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(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch)); - assert(val == std::string("Hello")); + const value val = content(http::evalExpr(mklist(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(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch)); - assert(val == std::string("Hello")); + const value val = content(http::evalExpr(mklist(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 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(std::string("echo"), blobs), "http://localhost:8090/test", ch)); + const value val = content(http::evalExpr(mklist(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 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 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 i = list() - << (list() << "name" << std::string("Apple")) - << (list() << "price" << std::string("$2.99")); - const list a = mklist(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + (list() + "name" + string("Apple")) + + (list() + "price" + string("$2.99")); + const list a = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); http::CURLSession ch; - const failable id = http::post(a, "http://localhost:8090/test", ch); + const failable 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 id = http::post(val, "http://localhost:8090/test", ch); + const failable 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 i = list() - << (list() << "name" << std::string("Apple")) - << (list() << "price" << std::string("$2.99")); - const list val = mklist(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + (list() + "name" + string("Apple")) + + (list() + "price" + string("$2.99")); + const list val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda 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 i = list() - << (list() << "name" << std::string("Apple")) - << (list() << "blob1" << blob) - << (list() << "blob2" << blob) - << (list() << "blob3" << blob) - << (list() << "blob4" << blob) - << (list() << "blob5" << blob) - << (list() << "price" << std::string("$2.99")); - const list val = mklist(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + (list() + "name" + string("Apple")) + + (list() + "blob1" + blob) + + (list() + "blob2" + blob) + + (list() + "blob3" + blob) + + (list() + "blob4" + blob) + + (list() + "blob5" + blob) + + (list() + "price" + string("$2.99")); + const list val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda 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 pl = postLoop(val, ch); @@ -194,7 +193,7 @@ struct postThreadLoop { const lambda l; const int threads; const gc_ptr w; - postThreadLoop(const lambda& l, const int threads) : l(l), threads(threads), w(new worker(threads)) { + postThreadLoop(const lambda& l, const int threads) : l(l), threads(threads), w(new (gc_new()) worker(threads)) { } const bool operator()() const { list > r = startPost(*w, threads, l); @@ -208,23 +207,83 @@ const bool testPostThreadPerf() { const int threads = 10; const list i = list() - << (list() << "name" << std::string("Apple")) - << (list() << "price" << std::string("$2.99")); - const value val = mklist(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + (list() + "name" + string("Apple")) + + (list() + "price" + string("$2.99")); + const value val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda pl= curry(lambda(postThread), count, val); const lambda 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 pl = postLoop(val, ch); + time(pl, 0, count); + return true; +} + +const list startPost(const int procs, const lambda& l) { + if (procs == 0) + return list(); + pid_t pid = fork(); + if (pid == 0) { + assert(l() == true); + exit(0); + } + return cons(pid, startPost(procs - 1, l)); +} + +const bool checkPost(const list& r) { + if (isNil(r)) + return true; + int status; + waitpid(car(r), &status, 0); + assert(status == 0); + return checkPost(cdr(r)); +} + +struct postForkLoop { + const lambda l; + const int procs; + postForkLoop(const lambda& l, const int procs) : l(l), procs(procs) { + } + const bool operator()() const { + list r = startPost(procs, l); + checkPost(r); + return true; + } +}; + +const bool testPostForkPerf() { + const int count = 50; + const int procs = 10; + + const list i = list() + + (list() + "name" + string("Apple")) + + (list() + "price" + string("$2.99")); + const value val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + const lambda pl= curry(lambda(postProc), count, val); + const lambda 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 i = list() - << (list() << "name" << std::string("Apple")) - << (list() << "price" << std::string("$2.99")); - const list a = mklist(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); + + (list() + "name" + string("Apple")) + + (list() + "price" + string("$2.99")); + const list a = mklist(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(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch)); - assert(val == std::string("hello world")); + const value val = content(http::evalExpr(mklist(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(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch)); - assert(val == std::string("hello world")); + const value val = content(http::evalExpr(mklist(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 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 +#include "string.hpp" #include "function.hpp" #include "list.hpp" @@ -34,24 +34,24 @@ namespace tuscany { namespace server { -const failable get(unused const list& params) { - return value(std::string("Hey")); +const failable get(unused const list& params) { + return value(string("Hey")); } -const failable post(unused const list& params) { - return value(std::string("1234")); +const failable post(unused const list& params) { + return value(string("1234")); } -const failable put(unused const list& params) { +const failable put(unused const list& params) { return value(true); } -const failable del(unused const list& params) { +const failable del(unused const list& params) { return value(true); } -const failable hello(const list& params) { - return value(std::string("hello ") + std::string(car(params))); +const failable hello(const list& params) { + return value(string("hello ") + string(car(params))); } } @@ -71,7 +71,7 @@ const tuscany::value eval(const tuscany::list& params) { return tuscany::server::del(cdr(params)); if (func == "hello") return tuscany::server::hello(cdr(params)); - return tuscany::mkfailure(std::string("Function not supported: ") + std::string(func)); + return tuscany::mkfailure(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 -#include -#include +#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&)>, std::string> readImplementation(const std::string path, const list& px) { - const failable ilib(dynlib(path + dynlibExt)); +const failable&)> > readImplementation(const string& path, const list& px) { + const failable ilib(dynlib(path + dynlibExt)); if (!hasContent(ilib)) - return mkfailure&)>, std::string>(reason(ilib)); + return mkfailure&)> >(reason(ilib)); - const failable&)>, std::string> impl(dynlambda&)>("eval", content(ilib))); + const failable&)> > impl(dynlambda&)>("eval", content(ilib))); if (!hasContent(impl)) return impl; return lambda&)>(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 -#include -#include -#include - +#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 implementations; }; @@ -80,16 +77,16 @@ public: * Convert a result represented as a content + failure pair to a * failable monad. */ -const failable failableResult(const list& v) { +const failable failableResult(const list& v) { if (isNil(cdr(v))) return car(v); - return mkfailure(cadr(v)); + return mkfailure(string(cadr(v))); } /** * Handle an HTTP GET. */ -const failable get(request_rec* r, const lambda&)>& impl) { +const failable get(request_rec* r, const lambda&)>& impl) { debug(r->uri, "modeval::get::uri"); // Inspect the query string @@ -102,12 +99,12 @@ const failable get(request_rec* r, const lambda val = failableResult(impl(cons(func, httpd::queryParams(args)))); + const failable val = failableResult(impl(cons(func, httpd::queryParams(args)))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(reason(val)); // Return JSON result json::JSONContext cx; @@ -115,58 +112,58 @@ const failable get(request_rec* r, const lambda path(httpd::path(r->uri)); + const list path(httpd::pathValues(r->uri)); if (isNil(cddr(path))) { - const failable val = failableResult(impl(cons("getall", list()))); + const failable val = failableResult(impl(cons("getall", list()))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(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 val = failableResult(impl(cons("get", mklist(caddr(path))))); + const failable val = failableResult(impl(cons("get", mklist(caddr(path))))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(reason(val)); return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(content(val))), "application/atom+xml;type=entry", r); } /** * Handle an HTTP POST. */ -const failable post(request_rec* r, const lambda&)>& impl) { - const list ls = httpd::read(r); +const failable post(request_rec* r, const lambda&)>& impl) { + const list 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 json = elementsToValues(content(json::readJSON(ls, cx))); const list > 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 params = (list)cadr(assoc(value("params"), args)); // Evaluate the request expression - const failable val = failableResult(impl(cons(func, params))); + const failable val = failableResult(impl(cons(func, params))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(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 val = failableResult(impl(cons("post", mklist(entry)))); + const failable val = failableResult(impl(cons("post", mklist(entry)))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(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 post(request_rec* r, const lambda put(request_rec* r, const lambda&)>& impl) { - const list ls = httpd::read(r); +const failable put(request_rec* r, const lambda&)>& impl) { + const list ls = httpd::read(r); debug(r->uri, "modeval::put::url"); debug(ls, "modeval::put::input"); // Evaluate an ATOM PUT request - const list path(httpd::path(r->uri)); + const list path(httpd::pathValues(r->uri)); const value entry = atom::entryValue(content(atom::readEntry(ls))); - const failable val = failableResult(impl(cons("put", mklist(caddr(path), entry)))); + const failable val = failableResult(impl(cons("put", mklist(caddr(path), entry)))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(reason(val)); if (val == value(false)) return HTTP_NOT_FOUND; return OK; @@ -199,14 +196,14 @@ const failable put(request_rec* r, const lambda del(request_rec* r, const lambda&)>& impl) { +const failable del(request_rec* r, const lambda&)>& impl) { debug(r->uri, "modeval::delete::url"); // Evaluate an ATOM delete request - const list path(httpd::path(r->uri)); - const failable val = failableResult(impl(cons("delete", mklist(caddr(path))))); + const list path(httpd::pathValues(r->uri)); + const failable val = failableResult(impl(cons("delete", mklist(caddr(path))))); if (!hasContent(val)) - return mkfailure(reason(val)); + return mkfailure(reason(val)); if (val == value(false)) return HTTP_NOT_FOUND; return OK; @@ -216,6 +213,7 @@ const failable del(request_rec* r, const lambdapool); 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(r, &mod_tuscany_eval); - const list path(httpd::path(r->uri)); + const list path(httpd::pathValues(r->uri)); const list impl(assoctree(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&)>(http::proxy(base + std::string(scdl::name(ref)))); +const value mkproxy(const value& ref, const string& base) { + return lambda&)>(http::proxy(base + string(scdl::name(ref)))); } -const list proxies(const list& refs, const std::string& base) { +const list proxies(const list& 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 proxies(const list& refs, const std::string& base) { * Return a configured component implementation. * For now only Scheme and C++ implementations are supported. */ -const failable&)>, std::string> readImplementation(const std::string& itype, const std::string& path, const list& px) { - if (itype.find(".scheme") != std::string::npos) +const failable&)> > readImplementation(const string& itype, const string& path, const list& 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&)>, std::string>("Unsupported implementation type: " + itype); + return mkfailure&)> >(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 px(proxies(scdl::references(comp), base.str())); + base << sc.wiringServerName << "/references/" << string(scdl::name(comp)) << "/"; + const list px(proxies(scdl::references(comp), str(base))); // Read and configure the implementation - const failable&)>, std::string> cimpl(readImplementation(elementName(impl), path, px)); + const failable&)> > cimpl(readImplementation(elementName(impl), path, px)); if (!hasContent(cimpl)) return reason(cimpl); return content(cimpl); @@ -320,10 +319,10 @@ const list componentToImplementationTree(DirConf& dc, ServerConf& sc, ser /** * Read the components declared in a composite. */ -const failable, std::string> readComponents(const std::string& path) { - std::ifstream is(path); - if (is.fail() || is.bad()) - return mkfailure, std::string>("Could not read composite: " + path); +const failable > readComponents(const string& path) { + ifstream is(path); + if (fail(is)) + return mkfailure >(string("Could not read composite: ") + path); return scdl::components(readXML(streamList(is))); } @@ -333,7 +332,7 @@ const failable, 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, std::string> comps = readComponents(dc.contributionPath + dc.compositeName); + const failable > 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(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(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(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(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 -#include -#include - +#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& params) const { const value expr = cons(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(), std::string("Could not evaluate expression")); + return mklist(value(), string("Could not evaluate expression")); return mklist(val); } }; @@ -78,13 +76,13 @@ struct evalImplementation { /** * Read a script component implementation. */ -const failable&)>, std::string> readImplementation(const std::string path, const list& px) { - std::ifstream is(path.c_str(), std::ios_base::in); - if (is.fail() || is.bad()) - return mkfailure&)>, std::string>("Could not read implementation: " + path); +const failable&)> > readImplementation(const string& path, const list& px) { + ifstream is(path); + if (fail(is)) + return mkfailure&)> >(string("Could not read implementation: ") + path); const value impl = eval::readScript(is); if (isNil(impl)) - return mkfailure&)>, std::string>("Could not read implementation: " + path); + return mkfailure&)> >(string("Could not read implementation: ") + path); return lambda&)>(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 -#include -#include -#include -#include - +#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 references; list 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(r, &mod_tuscany_wiring); - const list rpath(httpd::path(r->uri)); + const list rpath(httpd::pathValues(r->uri)); const list comp(assoctree(cadr(rpath), dc.references)); if (isNil(comp)) return HTTP_NOT_FOUND; @@ -105,26 +101,26 @@ int translateReference(request_rec *r) { const list ref(assoctree(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(r, &mod_tuscany_wiring); - const list path(httpd::path(r->uri)); + const list path(httpd::pathValues(r->uri)); const list 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, std::string> readComponents(const std::string& path) { - std::ifstream is(path); - if (is.fail() || is.bad()) - return mkfailure, std::string>("Could not read composite: " + path); +const failable > readComponents(const string& path) { + ifstream is(path); + if (fail(is)) + return mkfailure >(string("Could not read composite: ") + path); return scdl::components(readXML(streamList(is))); } @@ -261,23 +261,23 @@ const list componentReferenceToTargetTree(const list& c) { * Return a tree of service-URI-path + component-name pairs. Service-URI-paths are * represented as lists of URI path fragments. */ -const list defaultBindingURI(const std::string& cn, const std::string& sn) { +const list defaultBindingURI(const string& cn, const string& sn) { return mklist(cn, sn); } -const list bindingToComponentAssoc(const std::string& cn, const std::string& sn, const list& b) { +const list bindingToComponentAssoc(const string& cn, const string& sn, const list& b) { if (isNil(b)) return b; const value uri(scdl::uri(car(b))); if (isNil(uri)) return cons(mklist(defaultBindingURI(cn, sn), cn), bindingToComponentAssoc(cn, sn, cdr(b))); - return cons(mklist(httpd::path(std::string(uri).c_str()), cn), bindingToComponentAssoc(cn, sn, cdr(b))); + return cons(mklist(httpd::pathValues(c_str(string(uri))), cn), bindingToComponentAssoc(cn, sn, cdr(b))); } -const list serviceToComponentAssoc(const std::string& cn, const list& s) { +const list serviceToComponentAssoc(const string& cn, const list& s) { if (isNil(s)) return s; - const std::string sn(scdl::name(car(s))); + const string sn(scdl::name(car(s))); const list btoc(bindingToComponentAssoc(cn, sn, scdl::bindings(car(s)))); if (isNil(btoc)) return cons(mklist(defaultBindingURI(cn, sn), cn), serviceToComponentAssoc(cn, cdr(s))); @@ -300,7 +300,7 @@ const list uriToComponentTree(const list& c) { const bool confComponents(DirConf& dc) { if (dc.contributionPath == "" || dc.compositeName == "") return true; - const failable, std::string> comps = readComponents(dc.contributionPath + dc.compositeName); + const failable > 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(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(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); } } -- cgit v1.2.3