Get rid of TimeoutThread(s)

Use timer events instead. A side effect is that we now
support timeout in client mode. We also get much more
accurate timeouts. Previously starting a server with
a timeout of 4s, and GETing an endpoint that just looped,
would timeout somewhere between 3.5(!) and 8 seconds. Now
it times out between 4.0001 and 4.02s.

This will also make fixing pagelet timeouts much easier.
Esse commit está contido em:
mwilliams
2013-07-15 09:50:32 -07:00
commit de Sara Golemon
commit a946a8eb35
39 arquivos alterados com 248 adições e 468 exclusões
+1
Ver Arquivo
@@ -2,6 +2,7 @@ Future (next release):
- Implement assert with string arguments
- Implement RecursiveArrayIterator
- Implement php_strip_whitespace()
- Support for timeouts in cli mode
"Tamale" 7/22/2013
- Optimize vector-shaped Arrays (arrays with keys in range 0..size-1)
+13 -15
Ver Arquivo
@@ -41,6 +41,7 @@
#include "hphp/runtime/vm/unit.h"
#include "hphp/runtime/vm/event_hook.h"
#include "hphp/system/systemlib.h"
#include "folly/Format.h"
#include <limits>
@@ -631,22 +632,19 @@ Exception* generate_request_timeout_exception() {
Exception* ret = nullptr;
ThreadInfo *info = ThreadInfo::s_threadInfo.getNoCheck();
RequestInjectionData &data = info->m_reqInjectionData;
if (data.timeoutSeconds > 0) {
// This extra checking is needed, because there may be a race condition
// a TimeoutThread sets flag "true" right after an old request finishes and
// right before a new requets resets "started". In this case, we flag
// "timedout" back to "false".
if (time(0) - data.started >= data.timeoutSeconds) {
std::string exceptionMsg = "entire web request took longer than ";
exceptionMsg += boost::lexical_cast<std::string>(data.timeoutSeconds);
exceptionMsg += " seconds and timed out";
ArrayHolder exceptionStack;
if (RuntimeOption::InjectedStackTrace) {
exceptionStack = g_vmContext->debugBacktrace(false, true, true).get();
}
ret = new FatalErrorException(exceptionMsg, exceptionStack.get());
}
bool cli = RuntimeOption::ClientExecutionMode();
std::string exceptionMsg = cli ?
"Maximum execution time of " :
"entire web request took longer than ";
exceptionMsg += folly::to<std::string>(data.getTimeout());
exceptionMsg += cli ? " seconds exceeded" : " seconds and timed out";
ArrayHolder exceptionStack;
if (RuntimeOption::InjectedStackTrace) {
exceptionStack = g_vmContext->debugBacktrace(false, true, true).get();
}
ret = new FatalErrorException(exceptionMsg, exceptionStack.get());
return ret;
}
+4 -2
Ver Arquivo
@@ -59,7 +59,6 @@ const StaticString BaseExecutionContext::s_amp("&");
BaseExecutionContext::BaseExecutionContext() :
m_fp(nullptr), m_pc(nullptr),
m_transport(nullptr),
m_maxTime(RuntimeOption::RequestTimeoutSeconds),
m_cwd(Process::CurrentWorkingDirectory),
m_out(nullptr), m_implicitFlush(false), m_protectedLevel(0),
m_stdout(nullptr), m_stdoutData(nullptr),
@@ -494,6 +493,8 @@ void BaseExecutionContext::onRequestShutdown() {
}
void BaseExecutionContext::executeFunctions(CArrRef funcs) {
ThreadInfo::s_threadInfo->m_reqInjectionData.resetTimer();
for (ArrayIter iter(funcs); iter; ++iter) {
Array callback = iter.second().toArray();
vm_call_user_func(callback[s_name], callback[s_args].toArray());
@@ -770,7 +771,8 @@ void BaseExecutionContext::debuggerInfo(InfoVec &info) {
} else {
Add(info, "Max Memory", FormatSize(m_maxMemory));
}
Add(info, "Max Time", FormatTime(m_maxTime * 1000));
Add(info, "Max Time", FormatTime(ThreadInfo::s_threadInfo.getNoCheck()->
m_reqInjectionData.getTimeout() * 1000));
}
///////////////////////////////////////////////////////////////////////////////
-3
Ver Arquivo
@@ -228,8 +228,6 @@ public:
void setContentType(CStrRef mimetype, CStrRef charset);
int64_t getRequestMemoryMaxBytes() const { return m_maxMemory; }
void setRequestMemoryMaxBytes(int64_t max);
int64_t getRequestTimeLimit() const { return m_maxTime; }
void setRequestTimeLimit(int64_t limit) { m_maxTime = limit;}
String getCwd() const { return m_cwd;}
void setCwd(CStrRef cwd) { m_cwd = cwd;}
@@ -356,7 +354,6 @@ private:
// system settings
Transport *m_transport;
int64_t m_maxMemory;
int64_t m_maxTime;
String m_cwd;
// output buffering
+5 -5
Ver Arquivo
@@ -25,7 +25,6 @@
#include "hphp/runtime/base/builtin_functions.h"
#include "hphp/runtime/base/hphp_system.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/runtime/base/timeout_thread.h"
#include "hphp/runtime/ext/extension.h"
#include "hphp/util/lock.h"
@@ -241,7 +240,9 @@ bool IniSetting::Get(CStrRef name, String &value) {
return true;
}
if (name == s_max_execution_time || name == s_maximum_execution_time) {
value = String((int64_t)g_context->getRequestTimeLimit());
int64_t timeout = ThreadInfo::s_threadInfo.getNoCheck()->
m_reqInjectionData.getTimeout();
value = String(timeout);
return true;
}
if (name == s_hphp_build_id) {
@@ -321,9 +322,8 @@ bool IniSetting::Set(CStrRef name, CStrRef value) {
}
} else if (name == "max_execution_time" || name == "maximum_execution_time"){
int64_t limit = value.toInt64();
TimeoutThread::DeferTimeout(limit);
// Just for ini_get
g_context->setRequestTimeLimit(limit);
ThreadInfo::s_threadInfo.getNoCheck()->
m_reqInjectionData.setTimeout(limit);
return true;
} else if (name == "arg_separator.output") {
g_context->setArgSeparatorOutput(value);
+15 -2
Ver Arquivo
@@ -60,6 +60,7 @@
#include <boost/program_options/parsers.hpp>
#include <libgen.h>
#include <oniguruma.h>
#include <signal.h>
#include "libxml/parser.h"
#include "hphp/runtime/base/file_repository.h"
@@ -663,7 +664,7 @@ static int start_server(const std::string &username) {
// If we have any warmup requests, replay them before listening for
// real connections
for (auto& file : RuntimeOption::ServerWarmupRequests) {
HttpRequestHandler handler;
HttpRequestHandler handler(0);
ReplayTransport rt;
timespec start;
Timer::GetMonotonicTime(start);
@@ -1212,7 +1213,7 @@ static int execute_program_impl(int argc, char** argv) {
RuntimeOption::RecordInput = false;
set_execution_mode("server");
HttpServer server; // so we initialize runtime properly
HttpRequestHandler handler;
HttpRequestHandler handler(0);
for (int i = 0; i < po.count; i++) {
for (unsigned int j = 0; j < po.args.size(); j++) {
ReplayTransport rt;
@@ -1290,6 +1291,13 @@ extern "C" void hphp_fatal_error(const char *s) {
throw_fatal(s);
}
static void on_timeout(int sig, siginfo_t* info, void* context) {
if (sig == SIGVTALRM && info && info->si_code == SI_TIMER) {
auto data = (RequestInjectionData*)info->si_value.sival_ptr;
data->onTimeout();
}
}
void hphp_process_init() {
pthread_attr_t attr;
#ifndef __APPLE__
@@ -1300,6 +1308,11 @@ void hphp_process_init() {
Util::init_stack_limits(&attr);
pthread_attr_destroy(&attr);
struct sigaction action = {};
action.sa_sigaction = on_timeout;
action.sa_flags = SA_SIGINFO | SA_NODEFER;
sigaction(SIGVTALRM, &action, nullptr);
init_thread_locals();
ClassInfo::Load();
Process::InitProcessStatics();
+90 -1
Ver Arquivo
@@ -22,6 +22,8 @@
#include "hphp/util/lock.h"
#include "hphp/util/alloc.h"
#include <sys/mman.h>
using std::map;
namespace HPHP {
@@ -116,15 +118,97 @@ void ThreadInfo::setPendingException(Exception* e) {
}
void ThreadInfo::onSessionExit() {
m_reqInjectionData.setTimeout(0);
m_reqInjectionData.reset();
Transl::TargetCache::requestExit();
}
RequestInjectionData::~RequestInjectionData() {
if (m_hasTimer) {
timer_delete(m_timer_id);
}
}
void RequestInjectionData::onSessionInit() {
Transl::TargetCache::requestInit();
cflagsPtr = Transl::TargetCache::conditionFlagsPtr();
reset();
started = time(0);
}
void RequestInjectionData::onTimeout() {
setTimedOutFlag();
if (surprisePage) {
mprotect(surprisePage, sizeof(void*), PROT_NONE);
}
m_timerActive.store(false, std::memory_order_relaxed);
}
void RequestInjectionData::setSurprisePage(void* page) {
if (page != surprisePage) {
if (!page) {
if (m_timerActive.load(std::memory_order_relaxed)) {
setTimeout(0);
}
}
assert(!m_timerActive.load(std::memory_order_relaxed));
surprisePage = page;
}
}
void RequestInjectionData::setTimeout(int seconds) {
m_timeoutSeconds = seconds > 0 ? seconds : 0;
if (!m_hasTimer) {
if (!m_timeoutSeconds) {
// we don't have a timer, and we don't have a timeout
return;
}
sigevent sev;
memset(&sev, 0, sizeof(sev));
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGVTALRM;
sev.sigev_value.sival_ptr = this;
if (timer_create(CLOCK_REALTIME, &sev, &m_timer_id)) {
raise_error("Failed to set timeout: %s", strerror(errno));
}
m_hasTimer = true;
}
/*
* There is a potential race here. Callers want to assume that
* if they cancel the timeout (seconds = 0), they *wont* get
* a signal after they call this (although they may get a signal
* during the call).
* So we need to clear the timeout, wait (if necessary) for a
* pending signal to be handled, and then set the new timeout
*/
itimerspec ts = {};
itimerspec old;
timer_settime(m_timer_id, 0, &ts, &old);
if (!old.it_value.tv_sec && !old.it_value.tv_nsec) {
// the timer has gone off...
if (m_timerActive.load(std::memory_order_acquire)) {
// but m_timerActive is still set, so we haven't processed
// the signal yet.
// spin until its done.
while (m_timerActive.load(std::memory_order_relaxed)) {
}
}
}
if (m_timeoutSeconds) {
m_timerActive.store(true, std::memory_order_relaxed);
ts.it_value.tv_sec = m_timeoutSeconds;
timer_settime(m_timer_id, 0, &ts, nullptr);
} else {
m_timerActive.store(false, std::memory_order_relaxed);
}
}
void RequestInjectionData::resetTimer(int seconds /* = -1 */) {
auto data = &ThreadInfo::s_threadInfo->m_reqInjectionData;
if (seconds <= 0) seconds = data->getTimeout();
data->setTimeout(seconds);
data->clearTimedOutFlag();
}
void RequestInjectionData::reset() {
@@ -154,6 +238,11 @@ void RequestInjectionData::setTimedOutFlag() {
RequestInjectionData::TimedOutFlag);
}
void RequestInjectionData::clearTimedOutFlag() {
__sync_fetch_and_and(getConditionFlags(),
~RequestInjectionData::TimedOutFlag);
}
void RequestInjectionData::setSignaledFlag() {
__sync_fetch_and_or(getConditionFlags(),
RequestInjectionData::SignaledFlag);
-214
Ver Arquivo
@@ -1,214 +0,0 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/base/timeout_thread.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/util/lock.h"
#include "hphp/util/logger.h"
#include <sys/mman.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
// statics
// class defined in runtime/base/types.h
static void on_timer(int fd, short events, void *context) {
((TimeoutThread*)context)->onTimer(fd);
}
static void on_thread_stop(int fd, short events, void *context) {
event_base_loopbreak((struct event_base *)context);
}
///////////////////////////////////////////////////////////////////////////////
void TimeoutThread::DeferTimeout(int seconds) {
RequestInjectionData &data = ThreadInfo::s_threadInfo->m_reqInjectionData;
if (seconds > 0) {
// cheating by resetting started to desired timestamp
data.started = time(0) + (seconds - data.timeoutSeconds);
} else {
data.started = 0;
}
}
///////////////////////////////////////////////////////////////////////////////
TimeoutThread::TimeoutThread(int timeoutSeconds)
: m_nextId(0), m_stopped(false), m_timeoutSeconds(timeoutSeconds) {
m_eventBase = event_base_new();
// We need to open the pipe here because worker threads can start
// before the timeout thread starts
m_pipe.open();
}
TimeoutThread::~TimeoutThread() {
event_base_free(m_eventBase);
}
void TimeoutThread::registerRequestThread(RequestInjectionData* data) {
assert(data);
data->timeoutSeconds = m_timeoutSeconds;
{
Lock l(this);
int id = m_nextId++;
assert(!mapContains(m_clients, id));
m_clients[id].data = data;
m_pendingIds.push(id);
}
notifyPipe();
}
void TimeoutThread::removeRequestThread(RequestInjectionData* data) {
assert(data);
{
Lock l(this);
for (auto& pair : m_clients) {
if (pair.second.data == data) {
m_pendingIds.push(pair.first);
pair.second.data = nullptr;
break;
}
}
}
notifyPipe();
}
void TimeoutThread::checkForNewWorkers() {
// If m_timeoutSeconds is not a positive number, then workers threads
// are allowed to run forever, so don't bother creating timers for the
// workers
if (m_timeoutSeconds <= 0) {
return;
}
Lock lock(this);
for (; !m_pendingIds.empty(); m_pendingIds.pop()) {
int id = m_pendingIds.front();
assert(mapContains(m_clients, id));
ClientThread& ct = m_clients[id];
if (ct.data != nullptr) {
// This is a new thread and we have to register its timeout event
struct timeval timeout;
timeout.tv_usec = 0;
// +2 to make sure when it times out, this equation always holds:
// time(0) - RequestInjection::s_reqInjectionData->started >=
// m_timeoutSeconds
timeout.tv_sec = m_timeoutSeconds + 2;
event_set(&ct.e, id, 0, on_timer, this);
event_base_set(m_eventBase, &ct.e);
event_add(&ct.e, &timeout);
} else {
// This was a deleted thread and we have to remove its timeout event
event_del(&ct.e);
m_clients.erase(id);
}
}
}
void TimeoutThread::drainPipe() {
struct pollfd fdArray[1];
fdArray[0].fd = m_pipe.getOut();
fdArray[0].events = POLLIN;
while (poll(fdArray, 1, 0) > 0) {
char buf[256];
read(m_pipe.getOut(), buf, 256);
}
}
void TimeoutThread::notifyPipe() {
if (write(m_pipe.getIn(), "", 1) < 0) {
Logger::Warning("Error notifying the timeout thread that an event has "
"happened");
}
}
void TimeoutThread::run() {
event_set(&m_eventPipe, m_pipe.getOut(), EV_READ|EV_PERSIST,
on_thread_stop, m_eventBase);
event_base_set(m_eventBase, &m_eventPipe);
event_add(&m_eventPipe, nullptr);
while (!m_stopped) {
checkForNewWorkers();
event_base_loop(m_eventBase, EVLOOP_ONCE);
drainPipe();
}
for (auto& pair : m_clients) {
event_del(&pair.second.e);
}
event_del(&m_eventPipe);
}
void TimeoutThread::stop() {
m_stopped = true;
notifyPipe();
}
void TimeoutThread::onTimer(int index) {
Lock l(this);
assert(mapContains(m_clients, index));
ClientThread& ct = m_clients[index];
if (ct.data == nullptr) {
// The thread has been deleted but we haven't processed it
// yet. This is ok: just do nothing.
return;
}
event *e = &ct.e;
event_del(e);
RequestInjectionData *data = ct.data;
assert(data);
struct timeval timeout;
timeout.tv_usec = 0;
if (data->started > 0) {
time_t now = time(0);
int delta = now - data->started;
if (delta >= m_timeoutSeconds) {
timeout.tv_sec = m_timeoutSeconds + 2;
Lock l(data->surpriseLock);
data->setTimedOutFlag();
if (data->surprisePage) {
mprotect(data->surprisePage, sizeof(void*), PROT_NONE);
}
} else {
// Negative delta means start time was adjusted forward to give more time
if (delta < 0) delta = 0;
// otherwise, a new request started after we started the timer
timeout.tv_sec = m_timeoutSeconds - delta + 2;
}
} else {
// Another cycle of m_timeoutSeconds
timeout.tv_sec = m_timeoutSeconds;
}
event_set(e, index, 0, on_timer, this);
event_base_set(m_eventBase, e);
event_add(e, &timeout);
}
///////////////////////////////////////////////////////////////////////////////
}
-76
Ver Arquivo
@@ -1,76 +0,0 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_TIMEOUT_THREAD_H_
#define incl_HPHP_TIMEOUT_THREAD_H_
#include <queue>
#include "hphp/runtime/base/types.h"
#include "hphp/util/base.h"
#include "hphp/util/process.h"
#include "hphp/util/synchronizable.h"
#include <event.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
class TimeoutThread : public Synchronizable {
public:
static void DeferTimeout(int seconds);
public:
TimeoutThread(int timeoutSeconds);
~TimeoutThread();
void registerRequestThread(RequestInjectionData* data);
void removeRequestThread(RequestInjectionData* data);
void run();
void stop();
void onTimer(int index);
private:
void checkForNewWorkers();
void drainPipe();
void notifyPipe();
int m_nextId;
// m_pendingIds contains ids of threads that were added or removed
// and need to be processed by the worker thread
std::queue<int> m_pendingIds;
bool m_stopped;
event_base *m_eventBase;
struct ClientThread {
RequestInjectionData* data;
event e;
};
std::map<int, ClientThread> m_clients;
int m_timeoutSeconds;
// signal to wake up the thread
event m_eventPipe;
CPipe m_pipe;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_TIMEOUT_THREAD_H_
+20 -6
Ver Arquivo
@@ -23,15 +23,17 @@
#include "hphp/util/thread_local.h"
#include "hphp/util/mutex.h"
#include "hphp/util/case_insensitive.h"
#include <vector>
#include "hphp/runtime/base/macros.h"
#include "hphp/runtime/base/memory_manager.h"
#include <boost/static_assert.hpp>
#include <boost/intrusive_ptr.hpp>
#include <type_traits>
#include <stdint.h>
#include <atomic>
#include <limits>
#include <type_traits>
#include <vector>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -207,12 +209,15 @@ public:
static const ssize_t LastFlag = DebuggerSignalFlag;
RequestInjectionData()
: cflagsPtr(nullptr), surprisePage(nullptr), started(0), timeoutSeconds(-1),
: cflagsPtr(nullptr), surprisePage(nullptr),
m_timeoutSeconds(-1), m_hasTimer(false), m_timerActive(false),
m_debugger(false), m_dummySandbox(false),
m_debuggerIntr(false), m_coverage(false),
m_jit(false) {
}
~RequestInjectionData();
inline volatile ssize_t* getConditionFlags() {
assert(cflagsPtr);
return cflagsPtr;
@@ -222,17 +227,25 @@ public:
// somewhere in the thread's targetcache
void *surprisePage; // beginning address of page to
// protect for error conditions
Mutex surpriseLock; // mutex controlling access to surprisePage
time_t started; // when a request was started
int timeoutSeconds; // how many seconds to timeout
private:
timer_t m_timer_id; // id of our timer
int m_timeoutSeconds; // how many seconds to timeout
bool m_hasTimer; // Whether we've created our timer yet
std::atomic<bool> m_timerActive;
// Set true when we activate a timer,
// cleared when the signal handler runs
bool m_debugger; // whether there is a DebuggerProxy attached to me
bool m_dummySandbox; // indicating it is from a dummy sandbox thread
bool m_debuggerIntr; // indicating we should force interrupt for debugger
bool m_coverage; // is coverage being collected
bool m_jit; // is the jit enabled
public:
int getTimeout() const { return m_timeoutSeconds; }
void setTimeout(int seconds);
void resetTimer(int seconds = -1);
void setSurprisePage(void* page);
void onTimeout();
bool getJit() const { return m_jit; }
bool getDebugger() const { return m_debugger; }
void setDebugger(bool d) {
@@ -262,6 +275,7 @@ public:
void setMemExceededFlag();
void setTimedOutFlag();
void clearTimedOutFlag();
void setSignaledFlag();
void setEventHookFlag();
void clearEventHookFlag();
+3 -8
Ver Arquivo
@@ -26,7 +26,6 @@
#include "hphp/runtime/base/ini_setting.h"
#include "hphp/runtime/base/memory_manager.h"
#include "hphp/runtime/base/request_local.h"
#include "hphp/runtime/base/timeout_thread.h"
#include "hphp/runtime/base/runtime_error.h"
#include "hphp/runtime/base/zend_functions.h"
#include "hphp/runtime/base/zend_string.h"
@@ -847,13 +846,9 @@ bool f_set_magic_quotes_runtime(bool new_setting) {
}
void f_set_time_limit(int seconds) {
TimeoutThread::DeferTimeout(seconds);
// Just for ini_get
g_context->setRequestTimeLimit(seconds);
if (RuntimeOption::ClientExecutionMode() &&
seconds != 0) {
raise_warning("set_time_limit is not supported in client mode");
}
ThreadInfo *info = ThreadInfo::s_threadInfo.getNoCheck();
RequestInjectionData &data = info->m_reqInjectionData;
data.setTimeout(seconds);
}
String f_sys_get_temp_dir() {
+2 -2
Ver Arquivo
@@ -210,7 +210,7 @@ Variant f_xbox_process_call_message(CStrRef msg) {
}
int64_t f_xbox_get_thread_timeout() {
XboxServerInfoPtr server_info = XboxServer::GetServerInfo();
auto server_info = XboxServer::GetServerInfo();
if (server_info) {
return server_info->getMaxDuration();
}
@@ -222,7 +222,7 @@ void f_xbox_set_thread_timeout(int timeout) {
raise_warning("Cannot set timeout/duration to a negative number.");
return;
}
XboxServerInfoPtr server_info = XboxServer::GetServerInfo();
auto server_info = XboxServer::GetServerInfo();
if (server_info) {
server_info->setMaxDuration(timeout);
} else {
+2 -1
Ver Arquivo
@@ -62,7 +62,8 @@ IMPLEMENT_THREAD_LOCAL(AccessLog::ThreadData,
AccessLog AdminRequestHandler::s_accessLog(
&(AdminRequestHandler::getAccessLogThreadData));
AdminRequestHandler::AdminRequestHandler() {
AdminRequestHandler::AdminRequestHandler(int timeout) :
RequestHandler(timeout) {
}
// Helper machinery for jemalloc-stats-print command.
+1 -1
Ver Arquivo
@@ -28,7 +28,7 @@ public:
static AccessLog &GetAccessLog() { return s_accessLog; }
public:
AdminRequestHandler();
explicit AdminRequestHandler(int timeout);
// implementing RequestHandler
virtual void handleRequest(Transport *transport);
+7 -7
Ver Arquivo
@@ -43,9 +43,9 @@ IMPLEMENT_THREAD_LOCAL(AccessLog::ThreadData,
AccessLog HttpRequestHandler::s_accessLog(
&(HttpRequestHandler::getAccessLogThreadData));
HttpRequestHandler::HttpRequestHandler()
: m_pathTranslation(true)
,m_requestTimedOutOnQueue(ServiceData::createTimeseries(
HttpRequestHandler::HttpRequestHandler(int timeout)
: RequestHandler(timeout), m_pathTranslation(true)
, m_requestTimedOutOnQueue(ServiceData::createTimeseries(
"requests_timed_out_on_queue",
{ServiceData::StatsType::COUNT})) { }
@@ -135,9 +135,8 @@ void HttpRequestHandler::handleRequest(Transport *transport) {
// don't serve the request if it's been sitting in queue for longer than our
// allowed request timeout.
int requestTimeoutSeconds = (vhost->getRequestTimeoutSeconds() > 0 ?
vhost->getRequestTimeoutSeconds() :
RuntimeOption::RequestTimeoutSeconds);
int requestTimeoutSeconds =
vhost->getRequestTimeoutSeconds(RuntimeOption::RequestTimeoutSeconds);
if (requestTimeoutSeconds > 0) {
timespec now;
Timer::GetMonotonicTime(now);
@@ -269,7 +268,8 @@ void HttpRequestHandler::handleRequest(Transport *transport) {
// main body
hphp_session_init();
vhost->setRequestTimeoutSeconds();
ThreadInfo::s_threadInfo->m_reqInjectionData.
setTimeout(requestTimeoutSeconds);
bool ret = false;
try {
+1 -1
Ver Arquivo
@@ -38,7 +38,7 @@ public:
static AccessLog &GetAccessLog() { return s_accessLog; }
public:
HttpRequestHandler();
explicit HttpRequestHandler(int timeout);
// implementing RequestHandler
virtual void handleRequest(Transport *transport);
+9 -9
Ver Arquivo
@@ -59,7 +59,6 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
int startingThreadCount = RuntimeOption::ServerThreadCount;
uint32_t additionalThreads = 0;
RequestHandlerFactory handlerFactory;
if (RuntimeOption::ServerWarmupThrottleRequestCount > 0 &&
RuntimeOption::ServerThreadCount > kNumProcessors) {
startingThreadCount = kNumProcessors;
@@ -70,8 +69,7 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
(RuntimeOption::ServerType);
ServerOptions options
(RuntimeOption::ServerIP, RuntimeOption::ServerPort,
startingThreadCount,
std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds));
startingThreadCount);
options.m_serverFD = RuntimeOption::ServerPortFd;
options.m_sslFD = RuntimeOption::SSLPortFd;
options.m_takeoverFilename = RuntimeOption::TakeoverFilename;
@@ -81,12 +79,14 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
if (additionalThreads) {
auto handlerFactory = boost::make_shared<WarmupRequestHandlerFactory>(
m_pageServer, additionalThreads,
RuntimeOption::ServerWarmupThrottleRequestCount);
RuntimeOption::ServerWarmupThrottleRequestCount,
RuntimeOption::RequestTimeoutSeconds);
m_pageServer->setRequestHandlerFactory([handlerFactory] {
return handlerFactory->createHandler();
});
} else {
m_pageServer->setRequestHandlerFactory<HttpRequestHandler>();
m_pageServer->setRequestHandlerFactory<HttpRequestHandler>(
RuntimeOption::RequestTimeoutSeconds);
}
if (RuntimeOption::EnableSSL && m_sslCTX) {
@@ -97,9 +97,9 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
m_adminServer = ServerFactoryRegistry::createServer
(RuntimeOption::ServerType,
RuntimeOption::ServerIP, RuntimeOption::AdminServerPort,
RuntimeOption::AdminThreadCount,
std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds));
m_adminServer->setRequestHandlerFactory<AdminRequestHandler>();
RuntimeOption::AdminThreadCount);
m_adminServer->setRequestHandlerFactory<AdminRequestHandler>(
RuntimeOption::RequestTimeoutSeconds);
for (unsigned int i = 0; i < RuntimeOption::SatelliteServerInfos.size();
i++) {
@@ -139,7 +139,7 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
ReplayTransport rt;
rt.replayInput(hdf);
HttpRequestHandler handler;
HttpRequestHandler handler(0);
handler.handleRequest(&rt);
int code = rt.getResponseCode();
if (code == 200) {
+2 -25
Ver Arquivo
@@ -132,7 +132,6 @@ void LibEventWorker::doJob(LibEventJobPtr job) {
void LibEventWorker::onThreadEnter() {
assert(m_opaque);
LibEventServer *server = (LibEventServer*)m_opaque;
server->onThreadEnter();
if (RuntimeOption::EnableDebugger) {
Eval::Debugger::RegisterThread();
}
@@ -141,8 +140,6 @@ void LibEventWorker::onThreadEnter() {
void LibEventWorker::onThreadExit() {
assert(m_opaque);
LibEventServer *server = (LibEventServer*)m_opaque;
server->onThreadExit();
m_handler.reset();
}
@@ -150,12 +147,10 @@ void LibEventWorker::onThreadExit() {
// constructor and destructor
LibEventServer::LibEventServer(const std::string &address, int port,
int thread, int timeoutSeconds)
int thread)
: Server(address, port, thread),
m_accept_sock(-1),
m_accept_sock_ssl(-1),
m_timeoutThreadData(timeoutSeconds),
m_timeoutThread(&m_timeoutThreadData, &TimeoutThread::run),
m_dispatcher(thread, RuntimeOption::ServerThreadRoundRobin,
RuntimeOption::ServerThreadDropCacheTimeoutSeconds,
RuntimeOption::ServerThreadDropStack,
@@ -225,14 +220,10 @@ void LibEventServer::start() {
setStatus(RunStatus::RUNNING);
m_dispatcher.start();
m_dispatcherThread.start();
m_timeoutThread.start();
}
void LibEventServer::waitForEnd() {
m_dispatcherThread.waitForEnd();
m_timeoutThreadData.stop();
m_timeoutThread.waitForEnd();
}
void LibEventServer::dispatchWithTimeout(int timeoutSeconds) {
@@ -269,7 +260,7 @@ void LibEventServer::dispatch() {
}
m_responseQueue.close();
// flusing all remaining events
// flushing all remaining events
if (RuntimeOption::ServerGracefulShutdownWait) {
dispatchWithTimeout(RuntimeOption::ServerGracefulShutdownWait);
}
@@ -325,10 +316,6 @@ void LibEventServer::stop() {
}
m_dispatcherThread.waitForEnd();
// wait for the timeout thread to stop
m_timeoutThreadData.stop();
m_timeoutThread.waitForEnd();
evhttp_free(m_server);
m_server = nullptr;
}
@@ -370,16 +357,6 @@ int LibEventServer::getAcceptSocketSSL() {
///////////////////////////////////////////////////////////////////////////////
// request/response handling
void LibEventServer::onThreadEnter() {
m_timeoutThreadData.registerRequestThread
(&ThreadInfo::s_threadInfo->m_reqInjectionData);
}
void LibEventServer::onThreadExit() {
m_timeoutThreadData.removeRequestThread
(&ThreadInfo::s_threadInfo->m_reqInjectionData);
}
void LibEventServer::onRequest(struct evhttp_request *request) {
if (RuntimeOption::EnableKeepAlive &&
RuntimeOption::ConnectionTimeoutSeconds > 0) {
+1 -9
Ver Arquivo
@@ -19,7 +19,6 @@
#include "hphp/runtime/server/server.h"
#include "hphp/runtime/server/libevent_transport.h"
#include "hphp/runtime/base/timeout_thread.h"
#include "hphp/runtime/server/job_queue_vm_stack.h"
#include "hphp/util/job_queue.h"
#include "hphp/util/process.h"
@@ -127,8 +126,7 @@ public:
/**
* Constructor and destructor.
*/
LibEventServer(const std::string &address, int port, int thread,
int timeoutSeconds);
LibEventServer(const std::string &address, int port, int thread);
~LibEventServer();
// implementing Server
@@ -146,9 +144,6 @@ public:
}
int getLibEventConnectionCount();
void onThreadEnter();
void onThreadExit();
/**
* Request handler called by evhttp library.
*/
@@ -188,9 +183,6 @@ protected:
event m_eventStop;
CPipe m_pipeStop;
TimeoutThread m_timeoutThreadData;
AsyncFunc<TimeoutThread> m_timeoutThread;
private:
JobQueueDispatcher<LibEventJobPtr, LibEventWorker> m_dispatcher;
AsyncFunc<LibEventServer> m_dispatcherThread;
+3 -6
Ver Arquivo
@@ -33,8 +33,7 @@ public:
ServerPtr LibEventServerFactory::createServer(const ServerOptions& options) {
if (options.m_serverFD != -1 || options.m_sslFD != -1) {
auto const server = boost::make_shared<LibEventServerWithFd>
(options.m_address, options.m_port, options.m_numThreads,
options.m_timeout.count());
(options.m_address, options.m_port, options.m_numThreads);
server->setServerSocketFd(options.m_serverFD);
server->setSSLSocketFd(options.m_sslFD);
return server;
@@ -42,15 +41,13 @@ ServerPtr LibEventServerFactory::createServer(const ServerOptions& options) {
if (!options.m_takeoverFilename.empty()) {
auto const server = boost::make_shared<LibEventServerWithTakeover>
(options.m_address, options.m_port, options.m_numThreads,
options.m_timeout.count());
(options.m_address, options.m_port, options.m_numThreads);
server->setTransferFilename(options.m_takeoverFilename);
return server;
}
return boost::make_shared<LibEventServer>(options.m_address, options.m_port,
options.m_numThreads,
options.m_timeout.count());
options.m_numThreads);
}
///////////////////////////////////////////////////////////////////////////////
+2 -2
Ver Arquivo
@@ -24,8 +24,8 @@
namespace HPHP {
LibEventServerWithFd::LibEventServerWithFd
(const std::string &address, int port, int thread, int timeoutSeconds)
: LibEventServer(address, port, thread, timeoutSeconds)
(const std::string &address, int port, int thread)
: LibEventServer(address, port, thread)
{
}
+1 -2
Ver Arquivo
@@ -27,8 +27,7 @@ namespace HPHP {
*/
class LibEventServerWithFd : public LibEventServer {
public:
LibEventServerWithFd(const std::string &address, int port, int thread,
int timeoutSeconds);
LibEventServerWithFd(const std::string &address, int port, int thread);
void setServerSocketFd(int sock_fd) {
m_accept_sock = sock_fd;
@@ -83,8 +83,8 @@ static int fd_transfer_request_handler(
}
LibEventServerWithTakeover::LibEventServerWithTakeover
(const std::string &address, int port, int thread, int timeoutSeconds)
: LibEventServer(address, port, thread, timeoutSeconds),
(const std::string &address, int port, int thread)
: LibEventServer(address, port, thread),
m_delete_handle(nullptr),
m_took_over(false),
m_takeover_state(TakeoverState::NotStarted)
@@ -28,8 +28,7 @@ namespace HPHP {
*/
class LibEventServerWithTakeover : public LibEventServer {
public:
LibEventServerWithTakeover(const std::string &address, int port, int thread,
int timeoutSeconds);
LibEventServerWithTakeover(const std::string &address, int port, int thread);
virtual void stop();
+1 -1
Ver Arquivo
@@ -239,7 +239,7 @@ struct PageletWorker
virtual void doJob(PageletTransport *job) {
try {
job->onRequestStart(job->getStartTimer());
HttpRequestHandler().handleRequest(job);
HttpRequestHandler(0).handleRequest(job);
job->decRefCount();
} catch (...) {
Logger::Error("HttpRequestHandler leaked exceptions");
+5 -6
Ver Arquivo
@@ -32,8 +32,9 @@ using std::set;
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
RPCRequestHandler::RPCRequestHandler(bool info /* = true */)
: m_requestsSinceReset(0),
RPCRequestHandler::RPCRequestHandler(int timeout, bool info)
: RequestHandler(timeout),
m_requestsSinceReset(0),
m_reset(false),
m_logResets(info),
m_returnEncodeType(ReturnEncodeType::Json) {
@@ -145,7 +146,8 @@ void RPCRequestHandler::handleRequest(Transport *transport) {
HttpRequestHandler::GetAccessLog().log(transport, vhost);
return;
}
vhost->setRequestTimeoutSeconds();
ThreadInfo::s_threadInfo->m_reqInjectionData.
setTimeout(vhost->getRequestTimeoutSeconds(getDefaultTimeout()));
// resolve source root
string host = transport->getHeader("Host");
@@ -184,9 +186,6 @@ const StaticString
bool RPCRequestHandler::executePHPFunction(Transport *transport,
SourceRootInfo &sourceRootInfo,
ReturnEncodeType returnEncodeType) {
// reset timeout counter
ThreadInfo::s_threadInfo->m_reqInjectionData.started = time(0);
string rpcFunc = transport->getCommand();
{
ServerStatsHelper ssh("input");
+1 -1
Ver Arquivo
@@ -35,7 +35,7 @@ public:
Serialize = 2,
};
explicit RPCRequestHandler(bool info = true);
RPCRequestHandler(int timeout, bool info);
virtual ~RPCRequestHandler();
void setServerInfo(SatelliteServerInfoPtr info) { m_serverInfo = info;}
+9 -6
Ver Arquivo
@@ -92,8 +92,9 @@ public:
: m_allowedURLs(info->getURLs()) {
m_server = ServerFactoryRegistry::createServer
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
info->getThreadCount(), info->getTimeoutSeconds());
m_server->setRequestHandlerFactory<HttpRequestHandler>();
info->getThreadCount());
m_server->setRequestHandlerFactory<HttpRequestHandler>(
info->getTimeoutSeconds().count());
m_server->setUrlChecker(std::bind(&InternalPageServer::checkURL, this,
std::placeholders::_1));
}
@@ -131,8 +132,9 @@ public:
explicit DanglingPageServer(SatelliteServerInfoPtr info) {
m_server = ServerFactoryRegistry::createServer
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
info->getThreadCount(), info->getTimeoutSeconds());
m_server->setRequestHandlerFactory<HttpRequestHandler>();
info->getThreadCount());
m_server->setRequestHandlerFactory<HttpRequestHandler>(
info->getTimeoutSeconds().count());
}
virtual void start() {
@@ -154,9 +156,10 @@ public:
explicit RPCServer(SatelliteServerInfoPtr info) {
m_server = ServerFactoryRegistry::createServer
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
info->getThreadCount(), info->getTimeoutSeconds());
info->getThreadCount());
m_server->setRequestHandlerFactory([info] {
auto handler = make_unique<RPCRequestHandler>();
auto handler = make_unique<RPCRequestHandler>(
info->getTimeoutSeconds().count(), true);
handler->setServerInfo(info);
return handler;
});
+4 -6
Ver Arquivo
@@ -58,9 +58,8 @@ Server::Server(const std::string &address, int port, int threadCount)
ServerPtr ServerFactory::createServer(const std::string &address,
uint16_t port,
int numThreads,
std::chrono::seconds timeout) {
ServerOptions options(address, port, numThreads, timeout);
int numThreads) {
ServerOptions options(address, port, numThreads);
return createServer(options);
}
@@ -76,10 +75,9 @@ ServerFactoryRegistry *ServerFactoryRegistry::getInstance() {
ServerPtr ServerFactoryRegistry::createServer(const std::string &type,
const std::string &address,
uint16_t port,
int numThreads,
std::chrono::seconds timeout) {
int numThreads) {
auto factory = getInstance()->getFactory(type);
ServerOptions options(address, port, numThreads, timeout);
ServerOptions options(address, port, numThreads);
return factory->createServer(options);
}
+10 -11
Ver Arquivo
@@ -79,12 +79,16 @@ DECLARE_BOOST_TYPES(ServerFactory);
*/
class RequestHandler {
public:
explicit RequestHandler(int timeout) : m_timeout(timeout) {}
virtual ~RequestHandler() {}
/**
* Sub-class handles a request by implementing this function.
*/
virtual void handleRequest(Transport *transport) = 0;
int getDefaultTimeout() const { return m_timeout; }
private:
int m_timeout;
};
/**
@@ -142,9 +146,9 @@ public:
* GenericRequestHandlerFactory for the specified handler type.
*/
template<class TRequestHandler>
void setRequestHandlerFactory() {
setRequestHandlerFactory([] {
return std::unique_ptr<RequestHandler>(new TRequestHandler());
void setRequestHandlerFactory(int timeout) {
setRequestHandlerFactory([timeout] {
return std::unique_ptr<RequestHandler>(new TRequestHandler(timeout));
});
}
@@ -256,12 +260,10 @@ class ServerOptions {
public:
ServerOptions(const std::string &address,
uint16_t port,
int numThreads,
std::chrono::seconds timeout)
int numThreads)
: m_address(address),
m_port(port),
m_numThreads(numThreads),
m_timeout(timeout),
m_serverFD(-1),
m_sslFD(-1),
m_takeoverFilename() {
@@ -270,7 +272,6 @@ public:
std::string m_address;
uint16_t m_port;
int m_numThreads;
std::chrono::seconds m_timeout;
int m_serverFD;
int m_sslFD;
std::string m_takeoverFilename;
@@ -287,8 +288,7 @@ public:
ServerPtr createServer(const std::string &address,
uint16_t port,
int numThreads,
std::chrono::seconds timeout);
int numThreads);
};
/**
@@ -306,8 +306,7 @@ public:
static ServerPtr createServer(const std::string &type,
const std::string &address,
uint16_t port,
int numThreads,
std::chrono::seconds timeout);
int numThreads);
void registerFactory(const std::string &name,
const ServerFactoryPtr &factory);
+1 -1
Ver Arquivo
@@ -51,7 +51,7 @@ void ServiceThread::threadRun() {
hdf["url"] = m_url;
hdf["remote_host"] = RuntimeOption::ServerIP;
HttpRequestHandler handler;
HttpRequestHandler handler(0);
handler.disablePathTranslation();
do {
+3 -9
Ver Arquivo
@@ -19,7 +19,6 @@
#include "hphp/runtime/base/preg.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/runtime/base/comparisons.h"
#include "hphp/runtime/base/timeout_thread.h"
#include "hphp/runtime/base/string_util.h"
#include "hphp/util/util.h"
@@ -130,14 +129,9 @@ void VirtualHost::addAllowedDirectories(const std::vector<std::string>& dirs) {
}
}
void VirtualHost::setRequestTimeoutSeconds() const {
if (m_runtimeOption.requestTimeoutSeconds != -1) {
TimeoutThread::DeferTimeout(m_runtimeOption.requestTimeoutSeconds);
}
}
int VirtualHost::getRequestTimeoutSeconds() const {
return m_runtimeOption.requestTimeoutSeconds;
int VirtualHost::getRequestTimeoutSeconds(int defaultTimeout) const {
return m_runtimeOption.requestTimeoutSeconds < 0 ?
defaultTimeout : m_runtimeOption.requestTimeoutSeconds;
}
VirtualHost::VirtualHost() : m_disabled(false) {
+1 -2
Ver Arquivo
@@ -41,8 +41,7 @@ public:
void init(Hdf vh);
void addAllowedDirectories(const std::vector<std::string>& dirs);
void setRequestTimeoutSeconds() const;
int getRequestTimeoutSeconds() const;
int getRequestTimeoutSeconds(int defaultTimeout) const;
const std::string &getName() const { return m_name;}
const std::string &getPathTranslation() const { return m_pathTranslation;}
+1 -1
Ver Arquivo
@@ -32,7 +32,7 @@ void WarmupRequestHandler::handleRequest(Transport *transport) {
}
std::unique_ptr<RequestHandler> WarmupRequestHandlerFactory::createHandler() {
return make_unique<WarmupRequestHandler>(shared_from_this());
return make_unique<WarmupRequestHandler>(m_timeout, shared_from_this());
}
void WarmupRequestHandlerFactory::bumpReqCount() {
+7 -3
Ver Arquivo
@@ -32,8 +32,9 @@ DECLARE_BOOST_TYPES(WarmupRequestHandlerFactory);
*/
class WarmupRequestHandler : public RequestHandler {
public:
explicit WarmupRequestHandler(const WarmupRequestHandlerFactoryPtr& factory)
: m_factory(factory) {}
explicit WarmupRequestHandler(int timeout,
const WarmupRequestHandlerFactoryPtr& factory)
: RequestHandler(timeout), m_factory(factory), m_reqHandler(timeout) {}
virtual void handleRequest(Transport *transport);
@@ -47,10 +48,12 @@ class WarmupRequestHandlerFactory :
public:
WarmupRequestHandlerFactory(ServerPtr server,
uint32_t additionalThreads,
uint32_t reqCount)
uint32_t reqCount,
int timeout)
: m_additionalThreads(additionalThreads),
m_reqNumber(0),
m_warmupReqThreshold(reqCount),
m_timeout(timeout),
m_server(server) {}
std::unique_ptr<RequestHandler> createHandler();
@@ -61,6 +64,7 @@ private:
std::atomic<uint32_t> m_additionalThreads;
std::atomic<uint32_t> m_reqNumber;
uint32_t const m_warmupReqThreshold;
int m_timeout;
// The server has a shared pointer to us, so use a weak pointer to the
// server to avoid a circular reference.
ServerWeakPtr m_server;
+8 -5
Ver Arquivo
@@ -143,19 +143,22 @@ private:
string m_reqInitDoc;
};
///////////////////////////////////////////////////////////////////////////////
static IMPLEMENT_THREAD_LOCAL(XboxServerInfoPtr, s_xbox_server_info);
static IMPLEMENT_THREAD_LOCAL(string, s_xbox_prev_req_init_doc);
class XboxRequestHandler: public RPCRequestHandler {
public:
XboxRequestHandler() : RPCRequestHandler(Info) {}
XboxRequestHandler() : RPCRequestHandler(
(*s_xbox_server_info)->getTimeoutSeconds().count(), Info) {}
static bool Info;
};
bool XboxRequestHandler::Info = false;
///////////////////////////////////////////////////////////////////////////////
static IMPLEMENT_THREAD_LOCAL(XboxServerInfoPtr, s_xbox_server_info);
static IMPLEMENT_THREAD_LOCAL(XboxRequestHandler, s_xbox_request_handler);
static IMPLEMENT_THREAD_LOCAL(string, s_xbox_prev_req_init_doc);
///////////////////////////////////////////////////////////////////////////////
struct XboxWorker
+2 -8
Ver Arquivo
@@ -600,10 +600,7 @@ void
Stack::requestInit() {
m_elms = t_se->elms();
if (Transl::trustSigSegv) {
RequestInjectionData& data = ThreadInfo::s_threadInfo->m_reqInjectionData;
Lock l(data.surpriseLock);
assert(data.surprisePage == nullptr);
data.surprisePage = m_elms;
ThreadInfo::s_threadInfo->m_reqInjectionData.setSurprisePage(m_elms);
}
// Burn one element of the stack, to satisfy the constraint that
// valid m_top values always have the same high-order (>
@@ -626,11 +623,8 @@ void
Stack::requestExit() {
if (m_elms != nullptr) {
if (Transl::trustSigSegv) {
RequestInjectionData& data = ThreadInfo::s_threadInfo->m_reqInjectionData;
Lock l(data.surpriseLock);
assert(data.surprisePage == m_elms);
ThreadInfo::s_threadInfo->m_reqInjectionData.setSurprisePage(nullptr);
unprotect();
data.surprisePage = nullptr;
}
m_elms = nullptr;
}
+3 -2
Ver Arquivo
@@ -29,6 +29,7 @@
class TestCurlRequestHandler : public RequestHandler {
public:
explicit TestCurlRequestHandler(int timeout) : RequestHandler(timeout) {}
// implementing RequestHandler
virtual void handleRequest(Transport *transport) {
transport->addHeader("ECHOED", transport->getHeader("ECHO").c_str());
@@ -56,8 +57,8 @@ static ServerPtr runServer() {
for (s_server_port = PORT_MIN; s_server_port <= PORT_MAX; s_server_port++) {
try {
ServerPtr server = boost::make_shared<LibEventServer>(
"127.0.0.1", s_server_port, 4, -1);
server->setRequestHandlerFactory<TestCurlRequestHandler>();
"127.0.0.1", s_server_port, 4);
server->setRequestHandlerFactory<TestCurlRequestHandler>(0);
server->start();
return server;
+7 -5
Ver Arquivo
@@ -181,6 +181,7 @@ void TestServer::StopServer() {
class TestServerRequestHandler : public RequestHandler {
public:
explicit TestServerRequestHandler(int timeout) : RequestHandler(timeout) {}
// implementing RequestHandler
virtual void handleRequest(Transport *transport) {
// do nothing
@@ -191,8 +192,8 @@ static int find_server_port(int port_min, int port_max) {
for (int port = port_min; ; port++) {
try {
ServerPtr server = boost::make_shared<LibEventServer>(
"127.0.0.1", port, 50, -1);
server->setRequestHandlerFactory<TestServerRequestHandler>();
"127.0.0.1", port, 50);
server->setRequestHandlerFactory<TestServerRequestHandler>(30);
server->start();
server->stop();
server->waitForEnd();
@@ -420,7 +421,7 @@ public:
}
void process() {
HttpRequestHandler handler;
HttpRequestHandler handler(0);
for (unsigned int i = 0; i < 100; i++) {
handler.handleRequest(this);
}
@@ -531,6 +532,7 @@ bool TestServer::TestInheritFdServer() {
class EchoHandler : public RequestHandler {
public:
explicit EchoHandler(int timeout) : RequestHandler(timeout) {}
// implementing RequestHandler
virtual void handleRequest(Transport *transport) {
HeaderMap headers;
@@ -569,8 +571,8 @@ bool TestServer::TestHttpClient() {
for (s_server_port = PORT_MIN; s_server_port <= PORT_MAX; s_server_port++) {
try {
server = boost::make_shared<LibEventServer>(
"127.0.0.1", s_server_port, 50, -1);
server->setRequestHandlerFactory<EchoHandler>();
"127.0.0.1", s_server_port, 50);
server->setRequestHandlerFactory<EchoHandler>(0);
server->start();
break;
} catch (const FailedToListenException& e) {