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:
, min(minor)
{ }
void parse(const std::string& str) {
void parse(const std::string& str) override {
auto p = str.find('.');
std::string major, minor;
if (p != std::string::npos) {
......
......@@ -169,8 +169,6 @@ public:
new (&storage) T(std::forward<U>(u));
}
~Entry() = default;
const T& data() const {
return *reinterpret_cast<const T*>(&storage);
}
......@@ -228,8 +226,17 @@ public:
return head == tail;
}
std::unique_ptr<Entry> popSafe() {
return std::unique_ptr<Entry>(pop());
std::unique_ptr<T> popSafe() {
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:
......
......@@ -20,9 +20,14 @@
#include <openssl/ssl.h>
#endif /* PISTACHE_USE_SSL */
namespace Pistache {
namespace Http { namespace Private { class ParserBase; } }
namespace Tcp {
class Transport;
......@@ -33,7 +38,8 @@ public:
Peer();
Peer(const Address& addr);
~Peer() {}
Address address() const;
std::string hostname() const;
......@@ -43,22 +49,9 @@ public:
void associateSSL(void *ssl);
void *ssl(void) const;
void putData(std::string name, std::shared_ptr<void> data);
std::shared_ptr<void> getData(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);
}
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<Pistache::Http::Private::ParserBase> tryGetData(std::string name) const;
Async::Promise<ssize_t> send(const Buffer& buffer, int flags = 0);
......@@ -71,7 +64,7 @@ private:
Fd fd_;
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_;
};
......
......@@ -266,36 +266,34 @@ void
Transport::handleRequestsQueue() {
// Let's drain the queue
for (;;) {
auto entry = requestsQueue.popSafe();
if (!entry) break;
auto req = requestsQueue.popSafe();
if (!req) break;
auto &req = entry->data();
asyncSendRequestImpl(req);
asyncSendRequestImpl(*req);
}
}
void
Transport::handleConnectionQueue() {
for (;;) {
auto entry = connectionsQueue.popSafe();
if (!entry) break;
auto data = connectionsQueue.popSafe();
if (!data) break;
auto &data = entry->data();
auto conn = data.connection.lock();
auto conn = data->connection.lock();
if (!conn) {
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 (errno == EINPROGRESS) {
reactor()->registerFdOneShot(key(), conn->fd, NotifyOn::Write | NotifyOn::Hangup | NotifyOn::Shutdown);
}
else {
data.reject(Error::system("Failed to connect"));
data->reject(Error::system("Failed to connect"));
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(
void
Connection::processRequestQueue() {
for (;;) {
auto entry = requestsQueue.popSafe();
if (!entry) break;
auto req = requestsQueue.popSafe();
if (!req) break;
auto &req = entry->data();
performImpl(
req.request,
req.timeout, std::move(req.resolve), std::move(req.reject), std::move(req.onDone));
req->request,
req->timeout, std::move(req->resolve), std::move(req->reject), std::move(req->onDone));
}
}
......
......@@ -26,12 +26,12 @@ using namespace std;
namespace Pistache {
namespace Http {
template<typename H, typename Stream, typename... Args>
typename std::enable_if<Header::IsHeader<H>::value, Stream&>::type
writeHeader(Stream& stream, Args&& ...args) {
H header(std::forward<Args>(args)...);
stream << H::Name << ": ";
template<typename H, typename Stream, typename... Args>
typename std::enable_if<Header::IsHeader<H>::value, Stream&>::type
writeHeader(Stream& stream, Args&& ...args) {
H header(std::forward<Args>(args)...);
stream << H::Name << ": ";
header.write(stream);
stream << crlf;
......@@ -822,7 +822,7 @@ Timeout::onTimeout(uint64_t numWakeup) {
Private::Parser<Http::Request>&
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 {
}
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);
if (it != std::end(data_)) {
throw std::runtime_error("The data already exists");
......@@ -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)));
}
std::shared_ptr<void>
std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::getData(std::string name) const {
auto data = tryGetData(std::move(name));
if (data == nullptr) {
......@@ -87,7 +87,7 @@ Peer::getData(std::string name) const {
return data;
}
std::shared_ptr<void>
std::shared_ptr<Pistache::Http::Private::ParserBase>
Peer::tryGetData(std::string(name)) const {
auto it = data_.find(name);
if (it == std::end(data_)) return nullptr;
......
......@@ -354,16 +354,15 @@ void
Transport::handleWriteQueue() {
// Let's drain the queue
for (;;) {
auto entry = writesQueue.popSafe();
if (!entry) break;
auto write = writesQueue.popSafe();
if (!write) break;
auto &write = entry->data();
auto fd = write.peerFd;
auto fd = write->peerFd;
if (!isPeerFd(fd)) continue;
{
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);
......@@ -373,22 +372,20 @@ Transport::handleWriteQueue() {
void
Transport::handleTimerQueue() {
for (;;) {
auto entry = timersQueue.popSafe();
if (!entry) break;
auto timer = timersQueue.popSafe();
if (!timer) break;
auto &timer = entry->data();
armTimerMsImpl(std::move(timer));
armTimerMsImpl(std::move(*timer));
}
}
void
Transport::handlePeerQueue() {
for (;;) {
auto entry = peersQueue.popSafe();
if (!entry) break;
auto data = peersQueue.popSafe();
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)
struct HelloHandler : public Http::Handler {
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!");
}
};
......
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