Unverified Commit e4a9b227 authored by Kip's avatar Kip Committed by GitHub

Merge pull request #912 from hyperxor/fix_issue_842_and_refactoring

Fix issue #842 and small refactoring
parents f73f7baf 4e33c220
......@@ -548,7 +548,7 @@ namespace Pistache
class BodyStep : public Step
{
public:
static constexpr auto Id = Meta::Hash::fnv1a("Headers");
static constexpr auto Id = Meta::Hash::fnv1a("Body");
explicit BodyStep(Message* message_)
: Step(message_)
......@@ -616,17 +616,11 @@ namespace Pistache
State parse();
Step* step();
std::chrono::steady_clock::time_point time() const
{
return time_;
}
protected:
std::array<std::unique_ptr<Step>, StepsCount> allSteps;
size_t currentStep = 0;
std::chrono::steady_clock::time_point time_;
private:
ArrayStreamBuf<char> buffer;
StreamCursor cursor;
......@@ -643,7 +637,15 @@ namespace Pistache
void reset() override;
std::chrono::steady_clock::time_point time() const
{
return time_;
}
Request request;
private:
std::chrono::steady_clock::time_point time_;
};
template <>
......
......@@ -549,7 +549,6 @@ namespace Pistache
bool ParserBase::feed(const char* data, size_t len)
{
time_ = std::chrono::steady_clock::now();
return buffer.feed(data, len);
}
......@@ -559,7 +558,6 @@ namespace Pistache
cursor.reset();
currentStep = 0;
time_ = std::chrono::steady_clock::time_point(std::chrono::steady_clock::duration(0));
}
Step* ParserBase::step()
......@@ -933,11 +931,8 @@ namespace Pistache
return transport_->asyncWrite(fd, buffer)
.then<std::function<Async::Promise<ssize_t>(ssize_t)>,
std::function<void(std::exception_ptr&)>>(
[=](int /*l*/) {
return Async::Promise<ssize_t>(
[=](Async::Deferred<ssize_t> /*deferred*/) mutable {
return;
});
[=](ssize_t data) {
return Async::Promise<ssize_t>::resolved(data);
},
[=](std::exception_ptr& eptr) {
......@@ -1043,6 +1038,7 @@ namespace Pistache
Private::ParserImpl<Http::Request>::ParserImpl(size_t maxDataSize)
: ParserBase(maxDataSize)
, request()
, time_(std::chrono::steady_clock::now())
{
allSteps[0].reset(new RequestLineStep(&request));
allSteps[1].reset(new HeadersStep(&request));
......@@ -1054,6 +1050,7 @@ namespace Pistache
ParserBase::reset();
request = Request();
time_ = std::chrono::steady_clock::now();
}
Private::ParserImpl<Http::Response>::ParserImpl(size_t maxDataSize)
......
......@@ -107,10 +107,6 @@ namespace Pistache
handleTimer(std::move(entry_));
timers.erase(it->first);
}
else
{
throw std::runtime_error("Unknown fd");
}
}
else if (entry.isWritable())
{
......@@ -218,11 +214,6 @@ namespace Pistache
{
// Clean up buffers
Guard guard(toWriteLock);
auto& wq = toWrite[fd];
while (wq.size() > 0)
{
wq.pop_front();
}
toWrite.erase(fd);
}
......@@ -242,7 +233,7 @@ namespace Pistache
bool stop = false;
while (!stop)
{
Guard guard(toWriteLock);
std::unique_lock<std::mutex> lock(toWriteLock);
auto it = toWrite.find(fd);
......@@ -270,6 +261,7 @@ namespace Pistache
reactor()->modifyFd(key(), fd, NotifyOn::Read, Polling::Mode::Edge);
stop = true;
}
lock.unlock();
};
size_t totalWritten = buffer.offset();
......
......@@ -75,7 +75,6 @@ namespace Pistache
void TransportImpl::onReady(const Aio::FdSet& fds)
{
bool handled = false;
for (const auto& entry : fds)
{
if (entry.getTag() == Polling::Tag(timerFd))
......@@ -83,12 +82,11 @@ namespace Pistache
uint64_t wakeups;
::read(timerFd, &wakeups, sizeof wakeups);
checkIdlePeers();
handled = true;
break;
}
}
if (!handled)
Base::onReady(fds);
Base::onReady(fds);
}
void TransportImpl::setHeaderTimeout(std::chrono::milliseconds timeout)
......@@ -114,12 +112,12 @@ namespace Pistache
auto elapsed = now - time;
auto* step = parser->step();
if (step->id() == Private::RequestLineStep::Id)
if (step->id() == Private::RequestLineStep::Id || step->id() == Private::HeadersStep::Id)
{
if (elapsed > headerTimeout_ || elapsed > bodyTimeout_)
idlePeers.push_back(peer);
}
else if (step->id() == Private::HeadersStep::Id)
else if (step->id() == Private::BodyStep::Id)
{
if (elapsed > bodyTimeout_)
idlePeers.push_back(peer);
......@@ -208,7 +206,7 @@ namespace Pistache
void Endpoint::init(const Endpoint::Options& options)
{
listener.init(options.threads_, options.flags_, options.threadsName_);
listener.setTransportFactory([&] {
listener.setTransportFactory([this, options] {
if (!handler_)
throw std::runtime_error("Must call setHandler()");
......
This diff is collapsed.
......@@ -15,9 +15,10 @@ namespace Pistache
do \
{ \
auto ret = __VA_ARGS__; \
if (ret < 0) \
if (ret == -1) \
{ \
lastError_ = strerror(errno); \
lastErrno_ = errno; \
return false; \
} \
} while (0)
......@@ -66,9 +67,28 @@ namespace Pistache
return send(data.c_str(), data.size());
}
bool send(const void* data, size_t size)
bool send(const char* data, size_t len)
{
CLIENT_TRY(::send(fd_, data, size, 0));
size_t total = 0;
while (total < len)
{
ssize_t n = ::send(fd_, data + total, len - total, MSG_NOSIGNAL);
if (n == -1)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
else
{
CLIENT_TRY(n);
}
}
else
{
total += static_cast<size_t>(n);
}
}
return true;
}
......@@ -115,9 +135,15 @@ namespace Pistache
return lastError_;
}
int lastErrno() const
{
return lastErrno_;
}
private:
int fd_;
int fd_ = -1;
std::string lastError_;
int lastErrno_ = 0;
};
#undef CLIENT_TRY
......
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