diff options
Diffstat (limited to 'sca-cpp/trunk/modules/server')
-rw-r--r-- | sca-cpp/trunk/modules/server/client-test.cpp | 181 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/impl-test.cpp | 20 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-cpp.hpp | 13 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-eval.cpp | 126 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-scm.hpp | 20 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-wiring.cpp | 81 |
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); } } |