Proper move of App

This commit is contained in:
Alex Hultman
2019-01-22 09:16:05 +01:00
parent 98d329c912
commit db98f81986
2 changed files with 45 additions and 41 deletions
+4 -4
View File
@@ -12,11 +12,11 @@ int main(int argc, char **argv) {
int hello; int hello;
}; };
uWS::SSLApp({ auto app = uWS::SSLApp({
.key_file_name = "/home/alexhultman/key.pem", .key_file_name = "/home/alexhultman/key.pem",
.cert_file_name = "/home/alexhultman/cert.pem", .cert_file_name = "/home/alexhultman/cert.pem",
.passphrase = "1234" .passphrase = "1234"
}).get("/exit", [](auto *res, auto *req) { }).post("/exit", [](auto *res, auto *req) {
if (!token) { if (!token) {
res->end("Server already closed down!"); res->end("Server already closed down!");
@@ -60,12 +60,12 @@ int main(int argc, char **argv) {
PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); PerSocketData *perSocketData = (PerSocketData *) ws->getUserData();
std::cout << "OK per socket data: " << (perSocketData->hello == 13) << std::endl; std::cout << "OK per socket data: " << (perSocketData->hello == 13) << std::endl;
} }
}).listen(9001, [](auto *token) { })/*.listen(9001, [](auto *token) {
::token = token; ::token = token;
if (token) { if (token) {
std::cout << "Listening on port " << 3000 << std::endl; std::cout << "Listening on port " << 3000 << std::endl;
} }
}).run(); })*/.run();
std::cout << "Everything fine, falling through" << std::endl; std::cout << "Everything fine, falling through" << std::endl;
+41 -37
View File
@@ -46,7 +46,6 @@ struct TemplatedApp : StaticDispatch<SSL> {
private: private:
/* The app always owns at least one http context, but creates websocket contexts on demand */ /* The app always owns at least one http context, but creates websocket contexts on demand */
HttpContext<SSL> *httpContext; HttpContext<SSL> *httpContext;
std::vector<WebSocketContext<SSL, true> *> webSocketContexts; std::vector<WebSocketContext<SSL, true> *> webSocketContexts;
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE; using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
@@ -62,19 +61,27 @@ public:
} }
/* todo: Proper move semantics so to not allow copy-then-double-free and such problems of httpContext, etc. */
~TemplatedApp() { ~TemplatedApp() {
/* Let's just put everything here */ /* Let's just put everything here */
httpContext->free(); if (httpContext) {
httpContext->free();
for (auto *webSocketContext : webSocketContexts) { for (auto *webSocketContext : webSocketContexts) {
webSocketContext->free(); webSocketContext->free();
}
} }
} }
TemplatedApp(const TemplatedApp &other) { /* Disallow copying, only move */
TemplatedApp(const TemplatedApp &other) = delete;
TemplatedApp(TemplatedApp &&other) {
/* Move HttpContext */
httpContext = other.httpContext; httpContext = other.httpContext;
other.httpContext = nullptr;
/* Move webSocketContexts */
webSocketContexts = std::move(other.webSocketContexts);
} }
TemplatedApp(us_ssl_socket_context_options sslOptions = {}) { TemplatedApp(us_ssl_socket_context_options sslOptions = {}) {
@@ -93,7 +100,7 @@ public:
}; };
template <class UserData> template <class UserData>
TemplatedApp &ws(std::string pattern, WebSocketBehavior &&behavior) { TemplatedApp &&ws(std::string pattern, WebSocketBehavior &&behavior) {
/* Every route has its own websocket context with its own behavior and user data type */ /* Every route has its own websocket context with its own behavior and user data type */
auto *webSocketContext = WebSocketContext<SSL, true>::create(Loop::defaultLoop(), (typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE *) httpContext); auto *webSocketContext = WebSocketContext<SSL, true>::create(Loop::defaultLoop(), (typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE *) httpContext);
@@ -125,7 +132,7 @@ public:
/* Copy settings */ /* Copy settings */
webSocketContext->getExt()->maxPayloadLength = behavior.maxPayloadLength; webSocketContext->getExt()->maxPayloadLength = behavior.maxPayloadLength;
return get(pattern, [webSocketContext, this, behavior](auto *res, auto *req) { return std::move(get(pattern, [webSocketContext, this, behavior](auto *res, auto *req) {
/* If we have this header set, it's a websocket */ /* If we have this header set, it's a websocket */
std::string_view secWebSocketKey = req->getHeader("sec-websocket-key"); std::string_view secWebSocketKey = req->getHeader("sec-websocket-key");
if (secWebSocketKey.length()) { if (secWebSocketKey.length()) {
@@ -199,70 +206,67 @@ public:
/* For now we do not support having HTTP and websocket routes on the same URL */ /* For now we do not support having HTTP and websocket routes on the same URL */
res->close(); res->close();
} }
}); }));
// never called
return *this;
} }
TemplatedApp &get(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&get(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("get", pattern, handler); httpContext->onHttp("get", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &post(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&post(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("post", pattern, handler); httpContext->onHttp("post", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &options(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&options(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("options", pattern, handler); httpContext->onHttp("options", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &del(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&del(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("delete", pattern, handler); httpContext->onHttp("delete", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &patch(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&patch(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("patch", pattern, handler); httpContext->onHttp("patch", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &put(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&put(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("put", pattern, handler); httpContext->onHttp("put", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &head(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&head(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("head", pattern, handler); httpContext->onHttp("head", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &connect(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&connect(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("connect", pattern, handler); httpContext->onHttp("connect", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &trace(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&trace(std::string pattern, std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onHttp("trace", pattern, handler); httpContext->onHttp("trace", pattern, handler);
return *this; return std::move(*this);
} }
TemplatedApp &unhandled(std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) { TemplatedApp &&unhandled(std::function<void(HttpResponse<SSL> *, HttpRequest *)> handler) {
httpContext->onUnhandled(handler); httpContext->onUnhandled(handler);
return *this; return std::move(*this);
} }
TemplatedApp &listen(int port, std::function<void(us_listen_socket *)> handler) { TemplatedApp &&listen(int port, std::function<void(us_listen_socket *)> handler) {
handler(httpContext->listen(nullptr, port, 0)); handler(httpContext->listen(nullptr, port, 0));
return *this; return std::move(*this);
} }
TemplatedApp &run() { TemplatedApp &&run() {
uWS::run(); uWS::run();
return *this; return std::move(*this);
} }
}; };