Unverified Commit a95c97af authored by Dennis Jenkins's avatar Dennis Jenkins Committed by GitHub

Merge pull request #425 from AdrianCX/master

https://github.com/oktal/pistache/issues/399
parents 4a8ed93f 3094d044
...@@ -33,7 +33,7 @@ public: ...@@ -33,7 +33,7 @@ public:
, min(minor) , min(minor)
{ } { }
void parse(const std::string& str) { void parse(const std::string& str) override {
auto p = str.find('.'); auto p = str.find('.');
std::string major, minor; std::string major, minor;
if (p != std::string::npos) { if (p != std::string::npos) {
......
...@@ -169,8 +169,6 @@ public: ...@@ -169,8 +169,6 @@ public:
new (&storage) T(std::forward<U>(u)); new (&storage) T(std::forward<U>(u));
} }
~Entry() = default;
const T& data() const { const T& data() const {
return *reinterpret_cast<const T*>(&storage); return *reinterpret_cast<const T*>(&storage);
} }
...@@ -228,8 +226,17 @@ public: ...@@ -228,8 +226,17 @@ public:
return head == tail; return head == tail;
} }
std::unique_ptr<Entry> popSafe() { std::unique_ptr<T> popSafe() {
return std::unique_ptr<Entry>(pop()); std::unique_ptr<T> object;
std::unique_ptr<Entry> entry(pop());
if (entry)
{
object.reset(new T(std::move(entry->data())));
entry->data().~T();
}
return object;
} }
private: private:
......
...@@ -20,9 +20,14 @@ ...@@ -20,9 +20,14 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif /* PISTACHE_USE_SSL */ #endif /* PISTACHE_USE_SSL */
namespace Pistache { namespace Pistache {
namespace Http { namespace Private { class ParserBase; } }
namespace Tcp { namespace Tcp {
class Transport; class Transport;
...@@ -33,6 +38,7 @@ public: ...@@ -33,6 +38,7 @@ public:
Peer(); Peer();
Peer(const Address& addr); Peer(const Address& addr);
~Peer() {}
Address address() const; Address address() const;
std::string hostname() const; std::string hostname() const;
...@@ -43,22 +49,9 @@ public: ...@@ -43,22 +49,9 @@ public:
void associateSSL(void *ssl); void associateSSL(void *ssl);
void *ssl(void) const; void *ssl(void) const;
void putData(std::string name, std::shared_ptr<void> data); void putData(std::string name, std::shared_ptr<Pistache::Http::Private::ParserBase> data);
std::shared_ptr<Pistache::Http::Private::ParserBase> getData(std::string name) const;
std::shared_ptr<void> getData(std::string name) const; std::shared_ptr<Pistache::Http::Private::ParserBase> tryGetData(std::string name) const;
template<typename T>
std::shared_ptr<T> getData(std::string name) const {
return std::static_pointer_cast<T>(getData(std::move(name)));
}
std::shared_ptr<void> tryGetData(std::string name) const;
template<typename T>
std::shared_ptr<T> tryGetData(std::string name) const {
auto data = tryGetData(std::move(name));
if (data == nullptr) return nullptr;
return std::static_pointer_cast<T>(data);
}
Async::Promise<ssize_t> send(const Buffer& buffer, int flags = 0); Async::Promise<ssize_t> send(const Buffer& buffer, int flags = 0);
...@@ -71,7 +64,7 @@ private: ...@@ -71,7 +64,7 @@ private:
Fd fd_; Fd fd_;
std::string hostname_; std::string hostname_;
std::unordered_map<std::string, std::shared_ptr<void>> data_; std::unordered_map<std::string, std::shared_ptr<Pistache::Http::Private::ParserBase>> data_;
void *ssl_; void *ssl_;
}; };
......
...@@ -266,36 +266,34 @@ void ...@@ -266,36 +266,34 @@ void
Transport::handleRequestsQueue() { Transport::handleRequestsQueue() {
// Let's drain the queue // Let's drain the queue
for (;;) { for (;;) {
auto entry = requestsQueue.popSafe(); auto req = requestsQueue.popSafe();
if (!entry) break; if (!req) break;
auto &req = entry->data(); asyncSendRequestImpl(*req);
asyncSendRequestImpl(req);
} }
} }
void void
Transport::handleConnectionQueue() { Transport::handleConnectionQueue() {
for (;;) { for (;;) {
auto entry = connectionsQueue.popSafe(); auto data = connectionsQueue.popSafe();
if (!entry) break; if (!data) break;
auto &data = entry->data(); auto conn = data->connection.lock();
auto conn = data.connection.lock();
if (!conn) { if (!conn) {
throw std::runtime_error("Connection error"); throw std::runtime_error("Connection error");
} }
int res = ::connect(conn->fd, data.addr, data.addr_len); int res = ::connect(conn->fd, data->addr, data->addr_len);
if (res == -1) { if (res == -1) {
if (errno == EINPROGRESS) { if (errno == EINPROGRESS) {
reactor()->registerFdOneShot(key(), conn->fd, NotifyOn::Write | NotifyOn::Hangup | NotifyOn::Shutdown); reactor()->registerFdOneShot(key(), conn->fd, NotifyOn::Write | NotifyOn::Hangup | NotifyOn::Shutdown);
} }
else { else {
data.reject(Error::system("Failed to connect")); data->reject(Error::system("Failed to connect"));
continue; continue;
} }
} }
connections.insert(std::make_pair(conn->fd, std::move(data))); connections.insert(std::make_pair(conn->fd, std::move(*data)));
} }
} }
...@@ -552,13 +550,12 @@ Connection::performImpl( ...@@ -552,13 +550,12 @@ Connection::performImpl(
void void
Connection::processRequestQueue() { Connection::processRequestQueue() {
for (;;) { for (;;) {
auto entry = requestsQueue.popSafe(); auto req = requestsQueue.popSafe();
if (!entry) break; if (!req) break;
auto &req = entry->data();
performImpl( performImpl(
req.request, req->request,
req.timeout, std::move(req.resolve), std::move(req.reject), std::move(req.onDone)); req->timeout, std::move(req->resolve), std::move(req->reject), std::move(req->onDone));
} }
} }
......
...@@ -26,9 +26,9 @@ using namespace std; ...@@ -26,9 +26,9 @@ using namespace std;
namespace Pistache { namespace Pistache {
namespace Http { namespace Http {
template<typename H, typename Stream, typename... Args> template<typename H, typename Stream, typename... Args>
typename std::enable_if<Header::IsHeader<H>::value, Stream&>::type typename std::enable_if<Header::IsHeader<H>::value, Stream&>::type
writeHeader(Stream& stream, Args&& ...args) { writeHeader(Stream& stream, Args&& ...args) {
H header(std::forward<Args>(args)...); H header(std::forward<Args>(args)...);
stream << H::Name << ": "; stream << H::Name << ": ";
...@@ -822,7 +822,7 @@ Timeout::onTimeout(uint64_t numWakeup) { ...@@ -822,7 +822,7 @@ Timeout::onTimeout(uint64_t numWakeup) {
Private::Parser<Http::Request>& Private::Parser<Http::Request>&
Handler::getParser(const std::shared_ptr<Tcp::Peer>& peer) const { Handler::getParser(const std::shared_ptr<Tcp::Peer>& peer) const {
return *peer->getData<Private::Parser<Http::Request>>(ParserData); return static_cast<Private::Parser<Http::Request>&>(*peer->getData(ParserData));
} }
......
...@@ -68,7 +68,7 @@ Peer::fd() const { ...@@ -68,7 +68,7 @@ Peer::fd() const {
} }
void void
Peer::putData(std::string name, std::shared_ptr<void> data) { Peer::putData(std::string name, std::shared_ptr<Pistache::Http::Private::ParserBase> data) {
auto it = data_.find(name); auto it = data_.find(name);
if (it != std::end(data_)) { if (it != std::end(data_)) {
throw std::runtime_error("The data already exists"); throw std::runtime_error("The data already exists");
...@@ -77,7 +77,7 @@ Peer::putData(std::string name, std::shared_ptr<void> data) { ...@@ -77,7 +77,7 @@ Peer::putData(std::string name, std::shared_ptr<void> data) {
data_.insert(std::make_pair(std::move(name), std::move(data))); data_.insert(std::make_pair(std::move(name), std::move(data)));
} }
std::shared_ptr<void> std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::getData(std::string name) const { Peer::getData(std::string name) const {
auto data = tryGetData(std::move(name)); auto data = tryGetData(std::move(name));
if (data == nullptr) { if (data == nullptr) {
...@@ -87,7 +87,7 @@ Peer::getData(std::string name) const { ...@@ -87,7 +87,7 @@ Peer::getData(std::string name) const {
return data; return data;
} }
std::shared_ptr<void> std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::tryGetData(std::string(name)) const { Peer::tryGetData(std::string(name)) const {
auto it = data_.find(name); auto it = data_.find(name);
if (it == std::end(data_)) return nullptr; if (it == std::end(data_)) return nullptr;
......
...@@ -354,16 +354,15 @@ void ...@@ -354,16 +354,15 @@ void
Transport::handleWriteQueue() { Transport::handleWriteQueue() {
// Let's drain the queue // Let's drain the queue
for (;;) { for (;;) {
auto entry = writesQueue.popSafe(); auto write = writesQueue.popSafe();
if (!entry) break; if (!write) break;
auto &write = entry->data(); auto fd = write->peerFd;
auto fd = write.peerFd;
if (!isPeerFd(fd)) continue; if (!isPeerFd(fd)) continue;
{ {
Guard guard(toWriteLock); Guard guard(toWriteLock);
toWrite[fd].push_back(std::move(write)); toWrite[fd].push_back(std::move(*write));
} }
reactor()->modifyFd(key(), fd, NotifyOn::Read | NotifyOn::Write, Polling::Mode::Edge); reactor()->modifyFd(key(), fd, NotifyOn::Read | NotifyOn::Write, Polling::Mode::Edge);
...@@ -373,22 +372,20 @@ Transport::handleWriteQueue() { ...@@ -373,22 +372,20 @@ Transport::handleWriteQueue() {
void void
Transport::handleTimerQueue() { Transport::handleTimerQueue() {
for (;;) { for (;;) {
auto entry = timersQueue.popSafe(); auto timer = timersQueue.popSafe();
if (!entry) break; if (!timer) break;
auto &timer = entry->data(); armTimerMsImpl(std::move(*timer));
armTimerMsImpl(std::move(timer));
} }
} }
void void
Transport::handlePeerQueue() { Transport::handlePeerQueue() {
for (;;) { for (;;) {
auto entry = peersQueue.popSafe(); auto data = peersQueue.popSafe();
if (!entry) break; if (!data) break;
const auto &data = entry->data(); handlePeer(data->peer);
handlePeer(data.peer);
} }
} }
......
...@@ -21,7 +21,7 @@ static size_t write_cb(void *contents, size_t size, size_t nmemb, void *userp) ...@@ -21,7 +21,7 @@ static size_t write_cb(void *contents, size_t size, size_t nmemb, void *userp)
struct HelloHandler : public Http::Handler { struct HelloHandler : public Http::Handler {
HTTP_PROTOTYPE(HelloHandler) HTTP_PROTOTYPE(HelloHandler)
void onRequest(const Http::Request&, Http::ResponseWriter writer) { void onRequest(const Http::Request&, Http::ResponseWriter writer) override {
writer.send(Http::Code::Ok, "Hello, World!"); writer.send(Http::Code::Ok, "Hello, World!");
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment