nghttpx: Handle error from bufferevent_socket_new and event_base_new

This commit is contained in:
Tatsuhiro Tsujikawa 2013-09-24 23:17:53 +09:00
parent 57f5730756
commit a0326b3f2b
6 changed files with 69 additions and 13 deletions

View File

@ -59,7 +59,7 @@ namespace {
void ssl_acceptcb(evconnlistener *listener, int fd, void ssl_acceptcb(evconnlistener *listener, int fd,
sockaddr *addr, int addrlen, void *arg) sockaddr *addr, int addrlen, void *arg)
{ {
ListenHandler *handler = reinterpret_cast<ListenHandler*>(arg); auto handler = reinterpret_cast<ListenHandler*>(arg);
handler->accept_connection(fd, addr, addrlen); handler->accept_connection(fd, addr, addrlen);
} }
} // namespace } // namespace
@ -200,7 +200,7 @@ evconnlistener* create_evlistener(ListenHandler *handler, int family)
return 0; return 0;
} }
evconnlistener *evlistener = evconnlistener_new auto evlistener = evconnlistener_new
(handler->get_evbase(), (handler->get_evbase(),
ssl_acceptcb, ssl_acceptcb,
handler, handler,
@ -249,6 +249,10 @@ namespace {
int event_loop() int event_loop()
{ {
auto evbase = event_base_new(); auto evbase = event_base_new();
if(!evbase) {
LOG(FATAL) << "event_base_new() failed";
exit(EXIT_FAILURE);
}
SSL_CTX *sv_ssl_ctx, *cl_ssl_ctx; SSL_CTX *sv_ssl_ctx, *cl_ssl_ctx;
if(get_config()->client_mode) { if(get_config()->client_mode) {

View File

@ -74,6 +74,10 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream)
bev_ = bufferevent_socket_new bev_ = bufferevent_socket_new
(evbase, -1, (evbase, -1,
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
if(!bev_) {
DCLOG(INFO, this) << "bufferevent_socket_new() failed";
return SHRPX_ERR_NETWORK;
}
int rv = bufferevent_socket_connect int rv = bufferevent_socket_connect
(bev_, (bev_,
// TODO maybe not thread-safe? // TODO maybe not thread-safe?
@ -81,7 +85,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream)
get_config()->downstream_addrlen); get_config()->downstream_addrlen);
if(rv != 0) { if(rv != 0) {
bufferevent_free(bev_); bufferevent_free(bev_);
bev_ = 0; bev_ = nullptr;
return SHRPX_ERR_NETWORK; return SHRPX_ERR_NETWORK;
} }
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {

View File

@ -82,6 +82,13 @@ void ListenHandler::create_worker_thread(size_t num)
} }
auto bev = bufferevent_socket_new(evbase_, info->sv[0], auto bev = bufferevent_socket_new(evbase_, info->sv[0],
BEV_OPT_DEFER_CALLBACKS); BEV_OPT_DEFER_CALLBACKS);
if(!bev) {
LLOG(ERROR, this) << "bufferevent_socket_new() failed";
for(size_t j = 0; j < 2; ++j) {
close(info->sv[j]);
}
continue;
}
info->bev = bev; info->bev = bev;
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {
LLOG(INFO, this) << "Created thread #" << num_worker_; LLOG(INFO, this) << "Created thread #" << num_worker_;
@ -99,6 +106,10 @@ int ListenHandler::accept_connection(evutil_socket_t fd,
if(num_worker_ == 0) { if(num_worker_ == 0) {
auto client = ssl::accept_connection(evbase_, sv_ssl_ctx_, auto client = ssl::accept_connection(evbase_, sv_ssl_ctx_,
fd, addr, addrlen); fd, addr, addrlen);
if(!client) {
LLOG(ERROR, this) << "ClientHandler creation failed";
return 0;
}
client->set_spdy_session(spdy_); client->set_spdy_session(spdy_);
} else { } else {
size_t idx = worker_round_robin_cnt_ % num_worker_; size_t idx = worker_round_robin_cnt_ % num_worker_;

View File

@ -363,6 +363,10 @@ int SpdySession::initiate_connection()
<< get_config()->downstream_http_proxy_port; << get_config()->downstream_http_proxy_port;
} }
bev_ = bufferevent_socket_new(evbase_, -1, BEV_OPT_DEFER_CALLBACKS); bev_ = bufferevent_socket_new(evbase_, -1, BEV_OPT_DEFER_CALLBACKS);
if(!bev_) {
SSLOG(ERROR, this) << "bufferevent_socket_new() failed";
return SHRPX_ERR_NETWORK;
}
bufferevent_enable(bev_, EV_READ); bufferevent_enable(bev_, EV_READ);
bufferevent_set_timeouts(bev_, &get_config()->downstream_read_timeout, bufferevent_set_timeouts(bev_, &get_config()->downstream_read_timeout,
&get_config()->downstream_write_timeout); &get_config()->downstream_write_timeout);
@ -419,6 +423,11 @@ int SpdySession::initiate_connection()
bev_ = bufferevent_openssl_socket_new(evbase_, fd_, ssl_, bev_ = bufferevent_openssl_socket_new(evbase_, fd_, ssl_,
BUFFEREVENT_SSL_CONNECTING, BUFFEREVENT_SSL_CONNECTING,
BEV_OPT_DEFER_CALLBACKS); BEV_OPT_DEFER_CALLBACKS);
if(!bev_) {
SSLOG(ERROR, this) << "bufferevent_socket_new() failed";
SSL_free(ssl_);
return SHRPX_ERR_NETWORK;
}
rv = bufferevent_socket_connect rv = bufferevent_socket_connect
(bev_, (bev_,
// TODO maybe not thread-safe? // TODO maybe not thread-safe?
@ -427,6 +436,10 @@ int SpdySession::initiate_connection()
} else if(state_ == DISCONNECTED) { } else if(state_ == DISCONNECTED) {
// Without TLS and proxy. // Without TLS and proxy.
bev_ = bufferevent_socket_new(evbase_, -1, BEV_OPT_DEFER_CALLBACKS); bev_ = bufferevent_socket_new(evbase_, -1, BEV_OPT_DEFER_CALLBACKS);
if(!bev_) {
SSLOG(ERROR, this) << "bufferevent_socket_new() failed";
return SHRPX_ERR_NETWORK;
}
rv = bufferevent_socket_connect rv = bufferevent_socket_connect
(bev_, (bev_,
const_cast<sockaddr*>(&get_config()->downstream_addr.sa), const_cast<sockaddr*>(&get_config()->downstream_addr.sa),
@ -435,6 +448,10 @@ int SpdySession::initiate_connection()
assert(state_ == PROXY_CONNECTED); assert(state_ == PROXY_CONNECTED);
// Without TLS but with proxy. // Without TLS but with proxy.
bev_ = bufferevent_socket_new(evbase_, fd_, BEV_OPT_DEFER_CALLBACKS); bev_ = bufferevent_socket_new(evbase_, fd_, BEV_OPT_DEFER_CALLBACKS);
if(!bev_) {
SSLOG(ERROR, this) << "bufferevent_socket_new() failed";
return SHRPX_ERR_NETWORK;
}
// Connection already established. // Connection already established.
eventcb(bev_, BEV_EVENT_CONNECTED, this); eventcb(bev_, BEV_EVENT_CONNECTED, this);
// eventcb() has no return value. Check state_ to whether it was // eventcb() has no return value. Check state_ to whether it was

View File

@ -312,7 +312,7 @@ ClientHandler* accept_connection(event_base *evbase, SSL_CTX *ssl_ctx,
if(!ssl) { if(!ssl) {
LOG(ERROR) << "SSL_new() failed: " LOG(ERROR) << "SSL_new() failed: "
<< ERR_error_string(ERR_get_error(), nullptr); << ERR_error_string(ERR_get_error(), nullptr);
return 0; return nullptr;
} }
bev = bufferevent_openssl_socket_new bev = bufferevent_openssl_socket_new
(evbase, fd, ssl, (evbase, fd, ssl,
@ -320,10 +320,17 @@ ClientHandler* accept_connection(event_base *evbase, SSL_CTX *ssl_ctx,
} else { } else {
bev = bufferevent_socket_new(evbase, fd, BEV_OPT_DEFER_CALLBACKS); bev = bufferevent_socket_new(evbase, fd, BEV_OPT_DEFER_CALLBACKS);
} }
if(!bev) {
LOG(ERROR) << "bufferevent_socket_new() failed";
if(ssl) {
SSL_free(ssl);
}
return nullptr;
}
return new ClientHandler(bev, fd, ssl, host); return new ClientHandler(bev, fd, ssl, host);
} else { } else {
LOG(ERROR) << "getnameinfo() failed: " << gai_strerror(rv); LOG(ERROR) << "getnameinfo() failed: " << gai_strerror(rv);
return 0; return nullptr;
} }
} }

View File

@ -26,6 +26,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <memory> #include <memory>
#include <event.h> #include <event.h>
@ -75,20 +76,32 @@ void eventcb(bufferevent *bev, short events, void *arg)
void Worker::run() void Worker::run()
{ {
auto evbase = event_base_new(); auto evbase = std::unique_ptr<event_base, decltype(&event_base_free)>
auto bev = bufferevent_socket_new(evbase, fd_, BEV_OPT_DEFER_CALLBACKS); (event_base_new(), event_base_free);
SpdySession *spdy = nullptr; if(!evbase) {
LOG(ERROR) << "event_base_new() failed";
return;
}
auto bev = std::unique_ptr<bufferevent, decltype(&bufferevent_free)>
(bufferevent_socket_new(evbase.get(), fd_, BEV_OPT_DEFER_CALLBACKS),
bufferevent_free);
if(!bev) {
LOG(ERROR) << "bufferevent_socket_new() failed";
return;
}
std::unique_ptr<SpdySession> spdy;
if(get_config()->downstream_proto == PROTO_SPDY) { if(get_config()->downstream_proto == PROTO_SPDY) {
spdy = new SpdySession(evbase, cl_ssl_ctx_); spdy = util::make_unique<SpdySession>(evbase.get(), cl_ssl_ctx_);
if(spdy->init_notification() == -1) { if(spdy->init_notification() == -1) {
DIE(); DIE();
} }
} }
auto receiver = util::make_unique<ThreadEventReceiver>(sv_ssl_ctx_, spdy); auto receiver = util::make_unique<ThreadEventReceiver>(sv_ssl_ctx_,
bufferevent_enable(bev, EV_READ); spdy.get());
bufferevent_setcb(bev, readcb, 0, eventcb, receiver.get()); bufferevent_enable(bev.get(), EV_READ);
bufferevent_setcb(bev.get(), readcb, nullptr, eventcb, receiver.get());
event_base_loop(evbase, 0); event_base_loop(evbase.get(), 0);
} }
void start_threaded_worker(WorkerInfo *info) void start_threaded_worker(WorkerInfo *info)