@@ -0,0 +1,342 @@ | |||
/////////////////////////////////////////////////////////////////////////////// | |||
// | |||
// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com> | |||
// | |||
// See accompanying file COPYING.TXT file for licensing details. | |||
// | |||
/////////////////////////////////////////////////////////////////////////////// | |||
#ifndef CPPCMS_IMPL_BINDER | |||
#define CPPCMS_IMPL_BINDER | |||
#include <booster/aio/types.h> | |||
#include <booster/callback.h> | |||
namespace cppcms { | |||
namespace impl { | |||
// booster::aio::handler | |||
template<typename F,typename S> | |||
struct handler_binder_p0 : public booster::aio::handler::callable_type { | |||
F f_; | |||
S s_; | |||
handler_binder_p0(F const &f,S const &s) : f_(f), s_(s) {} | |||
void operator()() | |||
{ | |||
((*s_).*f_)(); | |||
} | |||
}; | |||
template<typename C,typename S> | |||
booster::aio::handler::pointer_type mfunc_to_handler(void (C::*f)(),S s) | |||
{ | |||
return new handler_binder_p0<void (C::*)(),S>(f,s); | |||
} | |||
template<typename F,typename S,typename P1> | |||
struct handler_binder_p1 : public booster::aio::handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
handler_binder_p1(F const &f,S const &s, P1 const &p1) : f_(f), s_(s), p1_(p1) {} | |||
void operator()() | |||
{ | |||
((*s_).*f_)(p1_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P1in> | |||
booster::aio::handler::pointer_type mfunc_to_handler(void (C::*f)(P1),S s,P1in const &p1) | |||
{ | |||
return new handler_binder_p1<void (C::*)(P1),S,P1in>(f,s,p1); | |||
} | |||
template<typename F,typename S,typename P1,typename P2> | |||
struct handler_binder_p2 : public booster::aio::handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
P2 p2_; | |||
handler_binder_p2(F const &f,S const &s, P1 const &p1,P2 const &p2) : f_(f), s_(s), p1_(p1),p2_(p2) {} | |||
void operator()() | |||
{ | |||
((*s_).*f_)(p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P2,typename P1in,typename P2in> | |||
booster::aio::handler::pointer_type mfunc_to_handler(void (C::*f)(P1,P2),S s,P1in const &p1,P2in const &p2) | |||
{ | |||
return new handler_binder_p2<void (C::*)(P1,P2),S,P1in,P2in>(f,s,p1,p2); | |||
} | |||
// booster::aio::event_handler | |||
template<typename F,typename S> | |||
struct event_handler_binder_p0 : public booster::aio::event_handler::callable_type { | |||
F f_; | |||
S s_; | |||
event_handler_binder_p0(F const &f,S const &s) : f_(f), s_(s) {} | |||
void operator()(booster::system::error_code const &e) | |||
{ | |||
((*s_).*f_)(e); | |||
} | |||
}; | |||
template<typename C,typename S> | |||
booster::aio::event_handler::pointer_type mfunc_to_event_handler(void (C::*f)(booster::system::error_code const &e),S s) | |||
{ | |||
return new event_handler_binder_p0<void (C::*)(booster::system::error_code const &),S>(f,s); | |||
} | |||
template<typename F,typename S,typename P1> | |||
struct event_handler_binder_p1 : public booster::aio::event_handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
event_handler_binder_p1(F const &f,S const &s, P1 const &p1) : f_(f), s_(s), p1_(p1) {} | |||
void operator()(booster::system::error_code const &e) | |||
{ | |||
((*s_).*f_)(e,p1_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P1in> | |||
booster::aio::event_handler::pointer_type mfunc_to_event_handler(void (C::*f)(booster::system::error_code const &,P1),S s,P1in const &p1) | |||
{ | |||
return new event_handler_binder_p1<void (C::*)(booster::system::error_code const &,P1),S,P1in>(f,s,p1); | |||
} | |||
template<typename F,typename S,typename P1,typename P2> | |||
struct event_handler_binder_p2 : public booster::aio::event_handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
P2 p2_; | |||
event_handler_binder_p2(F const &f,S const &s, P1 const &p1,P2 const &p2) : f_(f), s_(s), p1_(p1),p2_(p2) {} | |||
void operator()(booster::system::error_code const &e) | |||
{ | |||
((*s_).*f_)(e,p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P2,typename P1in,typename P2in> | |||
booster::aio::event_handler::pointer_type mfunc_to_event_handler(void (C::*f)(booster::system::error_code const &,P1,P2),S s,P1in const &p1,P2in const &p2) | |||
{ | |||
return new event_handler_binder_p2<void (C::*)(booster::system::error_code const &,P1,P2),S,P1in,P2in>(f,s,p1,p2); | |||
} | |||
// booster::aio::io_handler | |||
template<typename F,typename S> | |||
struct io_handler_binder_p0 : public booster::aio::io_handler::callable_type { | |||
F f_; | |||
S s_; | |||
io_handler_binder_p0(F const &f,S const &s) : f_(f), s_(s) {} | |||
void operator()(booster::system::error_code const &e,size_t l) | |||
{ | |||
((*s_).*f_)(e,l); | |||
} | |||
}; | |||
template<typename C,typename S> | |||
booster::aio::io_handler::pointer_type mfunc_to_io_handler(void (C::*f)(booster::system::error_code const &,size_t),S s) | |||
{ | |||
return new io_handler_binder_p0<void (C::*)(booster::system::error_code const &,size_t),S>(f,s); | |||
} | |||
template<typename F,typename S,typename P1> | |||
struct io_handler_binder_p1 : public booster::aio::io_handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
io_handler_binder_p1(F const &f,S const &s, P1 const &p1) : f_(f), s_(s), p1_(p1) {} | |||
void operator()(booster::system::error_code const &e,size_t l) | |||
{ | |||
((*s_).*f_)(e,l,p1_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P1in> | |||
booster::aio::io_handler::pointer_type mfunc_to_io_handler(void (C::*f)(booster::system::error_code const &,size_t,P1),S s,P1in const &p1) | |||
{ | |||
return new io_handler_binder_p1<void (C::*)(booster::system::error_code const &,size_t,P1),S,P1in>(f,s,p1); | |||
} | |||
template<typename F,typename S,typename P1,typename P2> | |||
struct io_handler_binder_p2 : public booster::aio::io_handler::callable_type { | |||
F f_; | |||
S s_; | |||
P1 p1_; | |||
P2 p2_; | |||
io_handler_binder_p2(F const &f,S const &s, P1 const &p1,P2 const &p2) : f_(f), s_(s), p1_(p1),p2_(p2) {} | |||
void operator()(booster::system::error_code const &e,size_t l) | |||
{ | |||
((*s_).*f_)(e,l,p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename S,typename P1,typename P2,typename P1in,typename P2in> | |||
booster::aio::io_handler::pointer_type mfunc_to_io_handler(void (C::*f)(booster::system::error_code const &,size_t,P1,P2),S s,P1in const &p1,P2in const &p2) | |||
{ | |||
return new io_handler_binder_p2<void (C::*)(booster::system::error_code const &,size_t,P1,P2),S,P1in,P2in>(f,s,p1,p2); | |||
} | |||
//// NON Member Functions | |||
// booster::aio::handler | |||
template<typename F,typename P1> | |||
struct handler_fbinder_p1 : public booster::aio::handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
handler_fbinder_p1(F const &f, P1 const &p1) : f_(f), p1_(p1) {} | |||
void operator()() | |||
{ | |||
f_(p1_); | |||
} | |||
}; | |||
template<typename C,typename P1> | |||
booster::aio::handler::pointer_type func_to_handler(C const &f,P1 const &p1) | |||
{ | |||
return new handler_fbinder_p1<C,P1>(f,p1); | |||
} | |||
template<typename F,typename P1,typename P2> | |||
struct handler_fbinder_p2 : public booster::aio::handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
P2 p2_; | |||
handler_fbinder_p2(F const &f, P1 const &p1,P2 const &p2) : f_(f), p1_(p1),p2_(p2) {} | |||
void operator()() | |||
{ | |||
f_(p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename P1,typename P2> | |||
booster::aio::handler::pointer_type func_to_handler(C const &f,P1 const &p1,P2 const &p2) | |||
{ | |||
return new handler_fbinder_p2<C,P1,P2>(f,p1,p2); | |||
} | |||
// booster::aio::event_handler | |||
template<typename F,typename P1> | |||
struct event_handler_fbinder_p1 : public booster::aio::event_handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
event_handler_fbinder_p1(F const &f, P1 const &p1) : f_(f), p1_(p1) {} | |||
void operator()(booster::system::error_code const &e) | |||
{ | |||
f_(e,p1_); | |||
} | |||
}; | |||
template<typename C,typename P1> | |||
booster::aio::event_handler::pointer_type func_to_event_handler(C const &f,P1 const &p1) | |||
{ | |||
return new event_handler_fbinder_p1<C,P1>(f,p1); | |||
} | |||
template<typename F,typename P1,typename P2> | |||
struct event_handler_fbinder_p2 : public booster::aio::event_handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
P2 p2_; | |||
event_handler_fbinder_p2(F const &f, P1 const &p1,P2 const &p2) : f_(f), p1_(p1),p2_(p2) {} | |||
void operator()(booster::system::error_code const &e) | |||
{ | |||
f_(e,p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename P1,typename P2> | |||
booster::aio::event_handler::pointer_type func_to_event_handler(C const &f,P1 const &p1,P2 const &p2) | |||
{ | |||
return new event_handler_fbinder_p2<C,P1,P2>(f,p1,p2); | |||
} | |||
// booster::aio::io_handler | |||
template<typename F,typename P1> | |||
struct io_handler_fbinder_p1 : public booster::aio::io_handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
io_handler_fbinder_p1(F const &f, P1 const &p1) : f_(f), p1_(p1) {} | |||
void operator()(booster::system::error_code const &e,size_t l) | |||
{ | |||
f_(e,l,p1_); | |||
} | |||
}; | |||
template<typename C,typename P1> | |||
booster::aio::io_handler::pointer_type func_to_io_handler(C f,P1 const &p1) | |||
{ | |||
return new io_handler_fbinder_p1<C,P1>(f,p1); | |||
} | |||
template<typename F,typename P1,typename P2> | |||
struct io_handler_fbinder_p2 : public booster::aio::io_handler::callable_type { | |||
F f_; | |||
P1 p1_; | |||
P2 p2_; | |||
io_handler_fbinder_p2(F const &f, P1 const &p1,P2 const &p2) : f_(f), p1_(p1),p2_(p2) {} | |||
void operator()(booster::system::error_code const &e,size_t l) | |||
{ | |||
f_(e,l,p1_,p2_); | |||
} | |||
}; | |||
template<typename C,typename P1,typename P2> | |||
booster::aio::io_handler::pointer_type func_to_io_handler(C f,P1 const &p1,P2 const &p2) | |||
{ | |||
return new io_handler_fbinder_p2<C,P1,P2>(f,p1,p2); | |||
} | |||
} // impl | |||
} // cppcms | |||
#endif |
@@ -163,7 +163,7 @@ namespace cgi { | |||
void set_error(ehandler const &h,std::string s); | |||
void on_headers_read(booster::system::error_code const &e,http::context *,ehandler const &h); | |||
void load_content(booster::system::error_code const &e,http::context *,ehandler const &h); | |||
void on_post_data_loaded(booster::system::error_code const &e,http::context *,ehandler const &h); | |||
void on_post_data_loaded(booster::system::error_code const &e,size_t ,http::context *,ehandler const &h); | |||
void on_some_multipart_read(booster::system::error_code const &e,size_t n,http::context *,ehandler const &h); | |||
void handle_eof(callback const &on_eof); | |||
void handle_http_error(int code,http::context *context,ehandler const &h); | |||
@@ -25,9 +25,7 @@ | |||
#include "cgi_api.h" | |||
#include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#include <cppcms/mem_bind.hpp> | |||
namespace cppcms { | |||
namespace impl { | |||
@@ -70,7 +68,7 @@ public: | |||
} | |||
read_interrupter_=fds[0]; | |||
write_interrupter_=fds[1]; | |||
thread_.reset(new booster::thread(boost::bind(&prefork_acceptor::run,this))); | |||
thread_.reset(new booster::thread(cppcms::util::mem_bind(&prefork_acceptor::run,this))); | |||
} | |||
private: | |||
void stop() | |||
@@ -185,7 +183,7 @@ private: | |||
} | |||
for(unsigned i=0;i<connections_.size();i++) { | |||
service_->post(boost::bind(&cppcms::http::context::run,connections_[i])); | |||
service_->post(cppcms::util::mem_bind(&cppcms::http::context::run,connections_[i])); | |||
} | |||
connections_.clear(); | |||
} // while loop | |||
@@ -26,12 +26,6 @@ | |||
#include <booster/locale/message.h> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
namespace cppcms { | |||
@@ -22,12 +22,7 @@ | |||
#include <scgi_header.h> | |||
#include <stdlib.h> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include "binder.h" | |||
#include <booster/log.h> | |||
#include <booster/aio/endpoint.h> | |||
@@ -55,7 +50,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||
} | |||
void async_run() | |||
{ | |||
scgi_.async_connect(ep_,boost::bind(&cgi_forwarder::on_connected,shared_from_this(),_1)); | |||
scgi_.async_connect(ep_,mfunc_to_event_handler(&cgi_forwarder::on_connected,shared_from_this())); | |||
} | |||
private: | |||
void on_connected(booster::system::error_code const &e) | |||
@@ -64,7 +59,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||
header_ = make_scgi_header(conn_->getenv(),0); | |||
scgi_.async_write( | |||
booster::aio::buffer(header_), | |||
boost::bind(&cgi_forwarder::on_header_sent,shared_from_this(),_1,_2)); | |||
mfunc_to_io_handler(&cgi_forwarder::on_header_sent,shared_from_this())); | |||
} | |||
void on_header_sent(booster::system::error_code const &e,size_t n) | |||
{ | |||
@@ -89,7 +84,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||
post_.resize(content_length_); | |||
} | |||
conn_->async_read_some(&post_.front(),post_.size(), | |||
boost::bind(&cgi_forwarder::on_post_data_read,shared_from_this(),_1,_2)); | |||
mfunc_to_io_handler(&cgi_forwarder::on_post_data_read,shared_from_this())); | |||
} | |||
else { | |||
response_.swap(post_); | |||
@@ -103,7 +98,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||
conn_->on_async_read_complete(); | |||
scgi_.async_write( | |||
booster::aio::buffer(&post_.front(),len), | |||
boost::bind(&cgi_forwarder::on_post_data_written,shared_from_this(),_1,_2)); | |||
mfunc_to_io_handler(&cgi_forwarder::on_post_data_written,shared_from_this())); | |||
} | |||
void on_post_data_written(booster::system::error_code const &e,size_t len) | |||
{ | |||
@@ -114,25 +109,25 @@ namespace cppcms { namespace impl { namespace cgi { | |||
void read_response() | |||
{ | |||
conn_->async_read_eof(boost::bind(&cgi_forwarder::cleanup,shared_from_this())); | |||
conn_->async_read_eof(mfunc_to_handler(&cgi_forwarder::cleanup,shared_from_this())); | |||
scgi_.async_read_some(booster::aio::buffer(response_), | |||
boost::bind(&cgi_forwarder::on_response_read,shared_from_this(),_1,_2)); | |||
mfunc_to_io_handler(&cgi_forwarder::on_response_read,shared_from_this())); | |||
} | |||
void on_response_read(booster::system::error_code const &e,size_t len) | |||
{ | |||
if(e) { | |||
conn_->async_write(booster::aio::const_buffer(),true,boost::bind(&cgi_forwarder::cleanup,shared_from_this())); | |||
conn_->async_write(booster::aio::const_buffer(),true,mfunc_to_event_handler(&cgi_forwarder::cleanup,shared_from_this())); | |||
return; | |||
} | |||
else { | |||
conn_->async_write(booster::aio::buffer(&response_.front(),len),false,boost::bind(&cgi_forwarder::on_response_written,shared_from_this(),_1)); | |||
conn_->async_write(booster::aio::buffer(&response_.front(),len),false,mfunc_to_event_handler(&cgi_forwarder::on_response_written,shared_from_this())); | |||
} | |||
} | |||
void on_response_written(booster::system::error_code const &e) | |||
{ | |||
if(e) { cleanup(); return; } | |||
scgi_.async_read_some(booster::aio::buffer(response_), | |||
boost::bind(&cgi_forwarder::on_response_read,shared_from_this(),_1,_2)); | |||
mfunc_to_io_handler(&cgi_forwarder::on_response_read,shared_from_this())); | |||
} | |||
void cleanup() | |||
@@ -142,6 +137,10 @@ namespace cppcms { namespace impl { namespace cgi { | |||
scgi_.shutdown(booster::aio::stream_socket::shut_rdwr,e); | |||
scgi_.close(e); | |||
} | |||
void cleanup(booster::system::error_code const &) | |||
{ | |||
cleanup(); | |||
} | |||
booster::shared_ptr<connection> conn_; | |||
booster::aio::stream_socket scgi_; | |||
@@ -186,10 +185,10 @@ void connection::async_prepare_request( http::context *context, | |||
socket().set_non_blocking(true,e); | |||
if(e) { | |||
BOOSTER_WARNING("cppcms") << "Failed to set nonblocking mode in socket " << e.message(); | |||
get_io_service().post(boost::bind(h,http::context::operation_aborted)); | |||
get_io_service().post(func_to_handler(h,http::context::operation_aborted)); | |||
return; | |||
} | |||
async_read_headers(boost::bind(&connection::on_headers_read,self(),_1,context,h)); | |||
async_read_headers(mfunc_to_event_handler(&connection::on_headers_read,self(),context,h)); | |||
} | |||
void connection::on_headers_read(booster::system::error_code const &e,http::context *context,ehandler const &h) | |||
@@ -215,7 +214,7 @@ void connection::on_headers_read(booster::system::error_code const &e,http::cont | |||
void connection::aync_wait_for_close_by_peer(booster::callback<void()> const &on_eof) | |||
{ | |||
async_read_eof(boost::bind(&connection::handle_eof,self(),on_eof)); | |||
async_read_eof(mfunc_to_handler(&connection::handle_eof,self(),on_eof)); | |||
} | |||
void connection::handle_eof(callback const &on_eof) | |||
@@ -268,10 +267,9 @@ void connection::handle_http_error(int code,http::context *context,ehandler cons | |||
"</body>\r\n" | |||
"</html>\r\n"; | |||
async_write(booster::aio::buffer(async_chunk_),true, | |||
boost::bind( | |||
mfunc_to_event_handler( | |||
&connection::handle_http_error_eof, | |||
self(), | |||
_1, | |||
code, | |||
h)); | |||
} | |||
@@ -331,10 +329,8 @@ void connection::load_content(booster::system::error_code const &e,http::context | |||
content_.clear(); | |||
content_.resize(8192); | |||
async_read_some(&content_.front(),content_.size(), | |||
boost::bind(&connection::on_some_multipart_read, | |||
mfunc_to_io_handler(&connection::on_some_multipart_read, | |||
self(), | |||
_1, | |||
_2, | |||
context, | |||
h)); | |||
} | |||
@@ -350,11 +346,11 @@ void connection::load_content(booster::system::error_code const &e,http::context | |||
content_.resize(content_length,0); | |||
async_read( &content_.front(), | |||
content_.size(), | |||
boost::bind(&connection::on_post_data_loaded,self(),_1,context,h)); | |||
mfunc_to_io_handler(&connection::on_post_data_loaded,self(),context,h)); | |||
} | |||
} | |||
else { | |||
on_post_data_loaded(booster::system::error_code(),context,h); | |||
on_post_data_loaded(booster::system::error_code(),0,context,h); | |||
} | |||
} | |||
@@ -401,17 +397,15 @@ void connection::on_some_multipart_read(booster::system::error_code const &e,siz | |||
} | |||
else { | |||
async_read_some(&content_.front(),content_.size(), | |||
boost::bind(&connection::on_some_multipart_read, | |||
mfunc_to_io_handler(&connection::on_some_multipart_read, | |||
self(), | |||
_1, | |||
_2, | |||
context, | |||
h)); | |||
} | |||
} | |||
void connection::on_post_data_loaded(booster::system::error_code const &e,http::context *context,ehandler const &h) | |||
void connection::on_post_data_loaded(booster::system::error_code const &e,size_t /*unused*/,http::context *context,ehandler const &h) | |||
{ | |||
if(e) { set_error(h,e.message()); return; } | |||
context->request().set_post_data(content_); | |||
@@ -21,14 +21,8 @@ | |||
#include <cppcms/config.h> | |||
#include <booster/aio/buffer.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include "binder.h" | |||
#include <utility> | |||
#include "cached_settings.h" | |||
@@ -76,16 +70,13 @@ namespace cgi { | |||
virtual void async_read_headers(handler const &h) | |||
{ | |||
reset_all(); | |||
async_read_record(boost::bind(&fastcgi::on_start_request,self(),_1,h)); | |||
async_read_record(mfunc_to_event_handler(&fastcgi::on_start_request,self(),h)); | |||
} | |||
virtual void async_read_some(void *p,size_t s,io_handler const &h) | |||
{ | |||
if(read_length_ == content_length_) { | |||
socket_.get_io_service().post(boost::bind( | |||
h, | |||
booster::system::error_code(errc::protocol_violation,cppcms_category), | |||
0)); | |||
socket_.get_io_service().post(h,booster::system::error_code(errc::protocol_violation,cppcms_category),0); | |||
return; | |||
} | |||
if(body_ptr_ < body_.size()) { | |||
@@ -102,29 +93,28 @@ namespace cgi { | |||
} | |||
if(read_length_ >= content_length_) { | |||
async_read_record(boost::bind( | |||
async_read_record(mfunc_to_event_handler( | |||
&fastcgi::on_read_stdin_eof_expected, | |||
self(), | |||
_1, | |||
h, | |||
s)); | |||
return; | |||
} | |||
socket_.get_io_service().post(boost::bind(h,booster::system::error_code(),s)); | |||
socket_.get_io_service().post(h,booster::system::error_code(),s); | |||
return; | |||
} | |||
else { | |||
async_read_record(boost::bind( | |||
async_read_record(mfunc_to_event_handler( | |||
&fastcgi::on_some_input_recieved, | |||
self(), | |||
_1,h,p,s)); | |||
h,std::make_pair(p,s))); | |||
return; | |||
} | |||
} | |||
virtual void on_async_write_start(){} | |||
virtual void on_async_write_progress(bool){} | |||
private: | |||
void on_some_input_recieved(booster::system::error_code const &e,io_handler const &h,void *p,size_t s) | |||
void on_some_input_recieved(booster::system::error_code const &e,io_handler const &h,std::pair<void *,size_t> in) | |||
{ | |||
if(e) { h(e,0); return; } | |||
if( header_.type!=fcgi_stdin | |||
@@ -134,7 +124,7 @@ namespace cgi { | |||
h(booster::system::error_code(errc::protocol_violation,cppcms_category),0); | |||
return; | |||
} | |||
async_read_some(p,s,h); | |||
async_read_some(in.first,in.second,h); | |||
} | |||
void on_read_stdin_eof_expected(booster::system::error_code const &e,io_handler const &h,size_t s) | |||
{ | |||
@@ -260,13 +250,31 @@ namespace cgi { | |||
eof_callback_ = false; | |||
} | |||
struct io_handler_to_handler { | |||
callback h; | |||
io_handler_to_handler(callback const &c) : h(c) {} | |||
void operator()(booster::system::error_code const &,size_t) | |||
{ | |||
h(); | |||
} | |||
}; | |||
struct io_handler_to_event_handler { | |||
handler h; | |||
io_handler_to_event_handler(handler const &c) : h(c) {} | |||
void operator()(booster::system::error_code const &e,size_t) | |||
{ | |||
h(e); | |||
} | |||
}; | |||
// This is not really correct because server may try | |||
// to multiplex or ask control... But meanwhile it is good enough | |||
virtual void async_read_eof(callback const &h) | |||
{ | |||
eof_callback_ = true; | |||
static char a; | |||
async_read_from_socket(&a,1,boost::bind(h)); | |||
async_read_from_socket(&a,1,io_handler_to_handler(h)); | |||
} | |||
private: | |||
@@ -419,9 +427,8 @@ namespace cgi { | |||
else if(name=="FCGI_MPXS_CONNS") | |||
add_pair(name,"0"); | |||
} | |||
async_send_respnse(boost::bind( &fastcgi::on_params_response_sent, | |||
async_send_respnse(mfunc_to_event_handler(&fastcgi::on_params_response_sent, | |||
self(), | |||
_1, | |||
h)); | |||
} | |||
else if(header_.type!=fcgi_begin_request) { | |||
@@ -443,9 +450,8 @@ namespace cgi { | |||
fcgi_end_request_body *body=reinterpret_cast<fcgi_end_request_body*>(&body_.front()); | |||
body->protocol_status=fcgi_unknown_role; | |||
body->to_net(); | |||
async_send_respnse(boost::bind( &fastcgi::on_params_response_sent, | |||
async_send_respnse(mfunc_to_event_handler(&fastcgi::on_params_response_sent, | |||
self(), | |||
_1, | |||
h)); | |||
return; | |||
} | |||
@@ -456,7 +462,7 @@ namespace cgi { | |||
params_record_expected(booster::system::error_code(),h); | |||
} | |||
else { | |||
async_read_record(boost::bind(&fastcgi::params_record_expected,self(),_1,h)); | |||
async_read_record(mfunc_to_event_handler(&fastcgi::params_record_expected,self(),h)); | |||
} | |||
} | |||
@@ -555,9 +561,8 @@ namespace cgi { | |||
continue; | |||
} | |||
else { | |||
async_read_record(boost::bind( &fastcgi::params_record_expected, | |||
async_read_record(mfunc_to_event_handler(&fastcgi::params_record_expected, | |||
self(), | |||
_1, | |||
h)); | |||
} | |||
} | |||
@@ -582,10 +587,9 @@ namespace cgi { | |||
stdin_eof_expected(booster::system::error_code(),h); | |||
} | |||
else { | |||
async_read_record(boost::bind( | |||
async_read_record(mfunc_to_event_handler( | |||
&fastcgi::stdin_eof_expected, | |||
self(), | |||
_1, | |||
h)); | |||
} | |||
return; | |||
@@ -622,7 +626,7 @@ namespace cgi { | |||
+ io::buffer(body_); | |||
header_.to_net(); | |||
socket_.async_write(packet,boost::bind(h,_1)); | |||
socket_.async_write(packet,io_handler_to_event_handler(h)); | |||
} | |||
@@ -652,9 +656,9 @@ namespace cgi { | |||
void async_read_record(handler const &h) | |||
{ | |||
async_read_from_socket(&header_,sizeof(header_), | |||
boost::bind( &fastcgi::on_header_read, | |||
mfunc_to_io_handler( | |||
&fastcgi::on_header_read, | |||
self(), | |||
_1, | |||
h)); | |||
} | |||
@@ -670,7 +674,7 @@ namespace cgi { | |||
} | |||
}; | |||
void on_header_read(booster::system::error_code const &e,handler const &h) | |||
void on_header_read(booster::system::error_code const &e,size_t /*unused read*/,handler const &h) | |||
{ | |||
if(e) { h(e); return; } | |||
header_.to_host(); | |||
@@ -787,12 +791,12 @@ namespace cgi { | |||
cache_start_+=n; | |||
} | |||
void async_read_from_socket(void *ptr,size_t n,booster::callback<void(booster::system::error_code const &e,size_t read)> const &cb) | |||
void async_read_from_socket(void *ptr,size_t n,booster::aio::io_handler const &cb) | |||
{ | |||
if(cache_end_ - cache_start_ >=n) { | |||
memcpy(ptr,&cache_[cache_start_],n); | |||
cache_start_+=n; | |||
socket_.get_io_service().post(boost::bind(cb,booster::system::error_code(),n)); | |||
socket_.get_io_service().post(cb,booster::system::error_code(),n); | |||
return; | |||
} | |||
if(cache_start_ == cache_end_) { | |||
@@ -811,21 +815,19 @@ namespace cgi { | |||
socket_.async_read_some( | |||
booster::aio::buffer(&cache_[cache_end_],cache_.size() - cache_end_), | |||
boost::bind( | |||
mfunc_to_io_handler( | |||
&fastcgi::on_some_read_from_socket, | |||
self(), | |||
_1, | |||
_2, | |||
cb, | |||
ptr, | |||
n)); | |||
std::make_pair(ptr,n))); | |||
} | |||
void on_some_read_from_socket( booster::system::error_code const &e, | |||
size_t read_size, | |||
booster::callback<void(booster::system::error_code const &e,size_t read)> const &cb, | |||
void *ptr, | |||
size_t expected_read_size) | |||
std::pair<void *,size_t> inp) | |||
{ | |||
void *ptr = inp.first; | |||
size_t expected_read_size = inp.second; | |||
cache_end_ += read_size; | |||
if(e) { | |||
cb(e,0); | |||
@@ -25,19 +25,7 @@ | |||
#include <scgi_header.h> | |||
#include "todec.h" | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
# if defined(CPPCMS_WIN32) && _WIN32_WINNT <= 0x0501 && !defined(BOOST_ASIO_DISABLE_IOCP) | |||
# define NO_CANCELIO | |||
# endif | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
# if defined(CPPCMS_WIN32) && _WIN32_WINNT <= 0x0501 && !defined(CPPCMS_BOOST_ASIO_DISABLE_IOCP) | |||
# define NO_CANCELIO | |||
# endif | |||
#endif | |||
#include "binder.h" | |||
namespace io = booster::aio; | |||
@@ -58,13 +46,11 @@ namespace cppcms { | |||
io::endpoint ep(ip_,port_); | |||
socket_.open(ep.family()); | |||
socket_.async_connect(ep, | |||
boost::bind( | |||
&tcp_pipe::on_connected, | |||
shared_from_this(),_1)); | |||
mfunc_to_event_handler(&tcp_pipe::on_connected,shared_from_this())); | |||
} | |||
private: | |||
void on_connected(booster::system::error_code e) | |||
void on_connected(booster::system::error_code const &e) | |||
{ | |||
if(e) { | |||
connection_->response().make_error_response(500); | |||
@@ -73,10 +59,10 @@ namespace cppcms { | |||
} | |||
socket_.async_write( | |||
io::buffer(data_), | |||
boost::bind(&tcp_pipe::on_written,shared_from_this(),_1)); | |||
mfunc_to_io_handler(&tcp_pipe::on_written,shared_from_this())); | |||
} | |||
void on_written(booster::system::error_code const &e) | |||
void on_written(booster::system::error_code const &e,size_t ) | |||
{ | |||
if(e) { | |||
connection_->response().make_error_response(500); | |||
@@ -85,13 +71,11 @@ namespace cppcms { | |||
} | |||
connection_->async_on_peer_reset(boost::bind(&tcp_pipe::on_peer_close,shared_from_this())); | |||
connection_->async_on_peer_reset(mfunc_to_handler(&tcp_pipe::on_peer_close,shared_from_this())); | |||
connection_->response().io_mode(http::response::asynchronous_raw); | |||
input_.resize(4096); | |||
socket_.async_read_some(io::buffer(input_), | |||
boost::bind(&tcp_pipe::on_read,shared_from_this(), | |||
_1, | |||
_2)); | |||
mfunc_to_io_handler(&tcp_pipe::on_read,shared_from_this())); | |||
} | |||
@@ -114,9 +98,7 @@ namespace cppcms { | |||
} | |||
else { | |||
socket_.async_read_some(io::buffer(input_), | |||
boost::bind(&tcp_pipe::on_read,shared_from_this(), | |||
_1, | |||
_2)); | |||
mfunc_to_io_handler(&tcp_pipe::on_read,shared_from_this())); | |||
} | |||
} | |||
@@ -26,12 +26,6 @@ | |||
#include <set> | |||
#include <cppcms/config.h> | |||
#include <cppcms/mem_bind.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include <fstream> | |||
#include "hello_world_view.h" | |||
@@ -61,6 +55,14 @@ public: | |||
response().finalize(); | |||
release_context()->async_complete_response(); | |||
} | |||
struct binder { | |||
chat *self; | |||
booster::shared_ptr<cppcms::http::context> context; | |||
void operator()() { | |||
self->remove_context(context); | |||
} | |||
}; | |||
void get(std::string no) | |||
{ | |||
std::cerr<<"Get:"<<waiters_.size()<<std::endl; | |||
@@ -73,11 +75,8 @@ public: | |||
else if(pos == messages_.size()) { | |||
booster::shared_ptr<cppcms::http::context> context=release_context(); | |||
waiters_.insert(context); | |||
context->async_on_peer_reset( | |||
boost::bind( | |||
&chat::remove_context, | |||
booster::intrusive_ptr<chat>(this), | |||
context)); | |||
binder bd = { this, context }; | |||
context->async_on_peer_reset(bd); | |||
} | |||
else { | |||
response().status(404); | |||
@@ -21,10 +21,9 @@ | |||
#include <list> | |||
#include <sstream> | |||
#include <algorithm> | |||
#include <cppcms_boost/bind.hpp> | |||
#include <stdio.h> | |||
namespace boost = cppcms_boost; | |||
#include "binder.h" | |||
// for testing only | |||
//#define CPPCMS_NO_SO_SNDTIMO | |||
@@ -193,7 +192,7 @@ namespace cgi { | |||
void async_read_some_headers(handler const &h) | |||
{ | |||
socket_.on_readable(boost::bind(&http::some_headers_data_read,self(),_1,h)); | |||
socket_.on_readable(mfunc_to_event_handler(&http::some_headers_data_read,self(),h)); | |||
update_time(); | |||
} | |||
virtual void async_read_headers(handler const &h) | |||
@@ -222,17 +221,16 @@ namespace cgi { | |||
n = socket_.read_some(booster::aio::buffer(input_body_),e); | |||
total_read_+=n; | |||
if(total_read_ > 16384) { | |||
h(booster::system::error_code(errc::protocol_violation,cppcms_category)); | |||
return; | |||
} | |||
input_body_.resize(n); | |||
for(;;) { | |||
using ::cppcms::http::impl::parser; | |||
switch(input_parser_.step()) { | |||
case parser::more_data: | |||
if(total_read_ > 16384) { | |||
h(booster::system::error_code(errc::protocol_violation,cppcms_category)); | |||
return; | |||
} | |||
// Assuming body_ptr == body.size() | |||
async_read_some_headers(h); | |||
return; | |||
@@ -304,7 +302,7 @@ namespace cgi { | |||
input_body_.clear(); | |||
input_body_ptr_=0; | |||
} | |||
socket_.get_io_service().post(boost::bind(h,booster::system::error_code(),s)); | |||
socket_.get_io_service().post(h,booster::system::error_code(),s); | |||
return; | |||
} | |||
if(input_body_.capacity()!=0) { | |||
@@ -416,11 +414,16 @@ namespace cgi { | |||
socket_.shutdown(io::stream_socket::shut_rdwr,e); | |||
socket_.close(e); | |||
} | |||
struct ignore_binder { | |||
callback h; | |||
void operator()(booster::system::error_code const &,size_t) { h(); } | |||
}; | |||
virtual void async_read_eof(callback const &h) | |||
{ | |||
watchdog_->add(self()); | |||
static char a; | |||
socket_.async_read_some(io::buffer(&a,1),boost::bind(h)); | |||
ignore_binder cb = { h }; | |||
socket_.async_read_some(io::buffer(&a,1),cb); | |||
} | |||
void on_async_write_start() | |||
@@ -611,9 +614,9 @@ namespace cgi { | |||
void error_response(char const *message,handler const &h) | |||
{ | |||
socket_.async_write(io::buffer(message,strlen(message)), | |||
boost::bind(&http::on_error_response_written,self(),_1,h)); | |||
mfunc_to_io_handler(&http::on_error_response_written,self(),h)); | |||
} | |||
void on_error_response_written(booster::system::error_code const &e,handler const &h) | |||
void on_error_response_written(booster::system::error_code const &e,size_t,handler const &h) | |||
{ | |||
if(e) { | |||
h(e); | |||
@@ -739,7 +742,7 @@ namespace cgi { | |||
} | |||
timer_.expires_from_now(booster::ptime(1)); | |||
timer_.async_wait(boost::bind(&http_watchdog::check,shared_from_this(),_1)); | |||
timer_.async_wait(mfunc_to_event_handler(&http_watchdog::check,shared_from_this())); | |||
} | |||
http *http_creator::operator()(cppcms::service &srv) const | |||
@@ -24,14 +24,7 @@ | |||
#include "cached_settings.h" | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include "binder.h" | |||
namespace cppcms { | |||
@@ -78,9 +71,30 @@ void context::skin(std::string const &skin) | |||
} | |||
namespace { | |||
struct ct_to_bool { | |||
void (context::*member)(bool r); | |||
booster::shared_ptr<context> ctx; | |||
void operator()(context::completion_type c) | |||
{ | |||
((*ctx).*member)(c!=context::operation_completed); | |||
} | |||
}; | |||
} | |||
void context::run() | |||
{ | |||
conn_->async_prepare_request(this,boost::bind(&context::on_request_ready,self(),_1)); | |||
ct_to_bool cb = { &context::on_request_ready, self() }; | |||
conn_->async_prepare_request(this,cb); | |||
} | |||
namespace { | |||
struct dispatcher { | |||
void (*func)(booster::intrusive_ptr<application>,std::string,bool); | |||
booster::intrusive_ptr<application> app; | |||
std::string url; | |||
void operator()() { func(app,url,true); } | |||
}; | |||
} | |||
void context::on_request_ready(bool error) | |||
@@ -109,16 +123,30 @@ void context::on_request_ready(bool error) | |||
dispatch(app,matched,false); | |||
} | |||
else { | |||
app->service().thread_pool().post(boost::bind(&context::dispatch,app,matched,true)); | |||
dispatcher dt; | |||
dt.func = &context::dispatch; | |||
dt.app = app; | |||
dt.url.swap(matched); | |||
app->service().thread_pool().post(dt); | |||
} | |||
} | |||
namespace { | |||
struct run_ctx { | |||
booster::shared_ptr<context> ctx; | |||
void operator()() { | |||
ctx->run(); | |||
} | |||
}; | |||
} | |||
void context::complete_response() | |||
{ | |||
response().finalize(); | |||
if(conn_->is_reuseable()) { | |||
booster::shared_ptr<context> cont(new context(conn_)); | |||
service().post(boost::bind(&context::run,cont)); | |||
run_ctx rn = { cont }; | |||
service().post(rn); | |||
} | |||
conn_.reset(); | |||
} | |||
@@ -180,14 +208,16 @@ void context::async_flush_output(context::handler const &h) | |||
h); | |||
} | |||
void context::async_complete_response() | |||
{ | |||
response().finalize(); | |||
if(response().io_mode() == http::response::asynchronous || response().io_mode() == http::response::asynchronous_raw) { | |||
ct_to_bool cb = { &context::try_restart, self() }; | |||
conn_->async_write_response( | |||
response(), | |||
true, | |||
boost::bind(&context::try_restart,self(),_1)); | |||
cb); | |||
return; | |||
} | |||
complete_response(); | |||
@@ -15,15 +15,11 @@ | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include <booster/aio/buffer.h> | |||
#include <string.h> | |||
#include "binder.h" | |||
namespace io = booster::aio; | |||
namespace cppcms { | |||
@@ -52,10 +48,9 @@ namespace cgi { | |||
buffer_.resize(16); | |||
socket_.async_read( | |||
io::buffer(buffer_), | |||
boost::bind( | |||
mfunc_to_io_handler( | |||
&scgi::on_first_read, | |||
self(), | |||
_1,_2, | |||
h)); | |||
} | |||
@@ -86,12 +81,12 @@ namespace cgi { | |||
} | |||
socket_.async_read( | |||
io::buffer(&buffer_[size],buffer_.size() - size), | |||
boost::bind( &scgi::on_headers_chunk_read, | |||
mfunc_to_io_handler( | |||
&scgi::on_headers_chunk_read, | |||
self(), | |||
_1, | |||
h)); | |||
} | |||
void on_headers_chunk_read(booster::system::error_code const &e,handler const &h) | |||
void on_headers_chunk_read(booster::system::error_code const &e,size_t ,handler const &h) | |||
{ | |||
if(e) { h(e); return; } | |||
if(buffer_.back()!=',') { | |||
@@ -145,11 +140,17 @@ namespace cgi { | |||
socket_.close(e); | |||
} | |||
struct ignore_io { | |||
callback h; | |||
void operator()(booster::system::error_code const &,size_t) { h(); } | |||
}; | |||
virtual void async_read_eof(callback const &h) | |||
{ | |||
eof_callback_ = true; | |||
static char a; | |||
socket_.async_read_some(io::buffer(&a,1),boost::bind(h)); | |||
ignore_io cb = { h }; | |||
socket_.async_read_some(io::buffer(&a,1),cb); | |||
} | |||
virtual booster::aio::stream_socket &socket() { return socket_; } | |||
@@ -31,6 +31,7 @@ | |||
#include <cppcms/cppcms_error.h> | |||
#include <cppcms/mount_point.h> | |||
#include <cppcms/forwarder.h> | |||
#include <cppcms/mem_bind.h> | |||
#include "cgi_acceptor.h" | |||
#ifndef CPPCMS_WIN32 | |||
#include "prefork_acceptor.h" | |||
@@ -73,12 +74,6 @@ | |||
#include <booster/nowide/fstream.h> | |||
#include <booster/thread.h> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#ifndef CPPCMS_WIN32 | |||
#include "daemonize.h" | |||
@@ -380,14 +375,25 @@ namespace { | |||
} // anon | |||
namespace { | |||
struct stop_binder { | |||
stop_binder(void (cppcms::service::*member)(),cppcms::service *s) : m(member),srv(s) {} | |||
void (cppcms::service::*m)(); | |||
cppcms::service *srv; | |||
void operator()(booster::system::error_code const &,size_t) | |||
{ | |||
(srv->*m)(); | |||
} | |||
}; | |||
} | |||
void service::setup_exit_handling() | |||
{ | |||
io::socket_pair(*impl_->sig_,*impl_->breaker_); | |||
static char c; | |||
impl_->breaker_->async_read_some(io::buffer(&c,1), | |||
boost::bind(&service::stop,this)); | |||
impl_->breaker_->async_read_some(io::buffer(&c,1),stop_binder(&service::stop,this)); | |||
impl_->notification_socket_=impl_->sig_->native(); | |||
@@ -532,9 +538,10 @@ void service::win_service_exec() | |||
void service::run_win_service() | |||
{ | |||
impl::winservice::instance().prepare(boost::bind(&service::win_service_prepare,this)); | |||
impl::winservice::instance().exec(boost::bind(&service::win_service_exec,this)); | |||
impl::winservice::instance().stop(boost::bind(&service::shutdown,this)); | |||
using cppcms::util::mem_bind; | |||
impl::winservice::instance().prepare(mem_bind(&service::win_service_prepare,this)); | |||
impl::winservice::instance().exec(mem_bind(&service::win_service_exec,this)); | |||
impl::winservice::instance().stop(mem_bind(&service::shutdown,this)); | |||
int argc=impl_->args_.size(); | |||
std::vector<char*> argv(argc+1,static_cast<char*>(0)); | |||
@@ -19,8 +19,7 @@ | |||
#include <booster/shared_object.h> | |||
#include <booster/enable_shared_from_this.h> | |||
#include <cppcms/config.h> | |||
#include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#include <cppcms/mem_bind.h> | |||
#include "aes_encryptor.h" | |||
@@ -38,6 +37,7 @@ namespace boost = cppcms_boost; | |||
#include <booster/aio/deadline_timer.h> | |||
#include <booster/callback.h> | |||
#include <booster/posix_time.h> | |||
#include <booster/system_error.h> | |||
#include "cached_settings.h" | |||
@@ -130,18 +130,20 @@ public: | |||
pool_(pool) | |||
{ | |||
} | |||
void async_run() const | |||
void async_run(booster::system::error_code const &e) | |||
{ | |||
service_->thread_pool().post(boost::bind(&gc_job::gc,shared_from_this())); | |||
if(e) | |||
return; | |||
service_->thread_pool().post(cppcms::util::mem_bind(&gc_job::gc,shared_from_this())); | |||
} | |||
private: | |||
void gc() const | |||
void gc() | |||
{ | |||
booster::ptime start = booster::ptime::now(); | |||
booster::ptime restart = start + booster::ptime::from_number(freq_); | |||
pool_->backend_->gc(); | |||
timer_->expires_at(restart); | |||
timer_->async_wait(boost::bind(&gc_job::async_run,shared_from_this())); | |||
timer_->async_wait(cppcms::util::mem_bind(&gc_job::async_run,shared_from_this())); | |||
} | |||
booster::shared_ptr<booster::aio::deadline_timer> timer_; | |||
service *service_; | |||
@@ -318,7 +320,7 @@ void session_pool::init() | |||
throw cppcms_error("Unknown location"); | |||
if(service_) | |||
service_->after_fork(boost::bind(&session_pool::after_fork,this)); | |||
service_->after_fork(cppcms::util::mem_bind(&session_pool::after_fork,this)); | |||
} | |||
session_pool::session_pool(service &srv) : | |||
@@ -342,7 +344,7 @@ void session_pool::after_fork() | |||
double frequency = service_->settings().get("session.gc",0.0); | |||
if(frequency > 0) { | |||
booster::shared_ptr<gc_job> job(new gc_job(service_,frequency,this)); | |||
job->async_run(); | |||
job->async_run(booster::system::error_code()); | |||
} | |||
} | |||
} | |||
@@ -20,7 +20,6 @@ | |||
#include <cppcms/cppcms_error.h> | |||
#include <cppcms/config.h> | |||
#include <cppcms/session_storage.h> | |||
#include <cppcms_boost/bind.hpp> | |||
#include <booster/shared_ptr.h> | |||
#include <booster/enable_shared_from_this.h> | |||
#include <booster/thread.h> | |||
@@ -29,6 +28,8 @@ | |||
#include <booster/aio/endpoint.h> | |||
#include <booster/aio/buffer.h> | |||
#include <booster/aio/deadline_timer.h> | |||
#include <cppcms/mem_bind.h> | |||
#include "binder.h" | |||
#include <booster/log.h> | |||
#include <time.h> | |||
#include <stdlib.h> | |||
@@ -38,12 +39,11 @@ | |||
#include "tcp_cache_server.h" | |||
namespace boost = cppcms_boost; | |||
namespace cppcms { | |||
namespace impl { | |||
using cppcms::util::mem_bind; | |||
namespace io = booster::aio; | |||
class tcp_cache_service::session : public booster::enable_shared_from_this<tcp_cache_service::session> { | |||
@@ -72,21 +72,19 @@ public: | |||
void run() | |||
{ | |||
socket_.async_read(io::buffer(&hin_,sizeof(hin_)), | |||
boost::bind(&session::on_header_in,shared_from_this(), | |||
_1)); | |||
mfunc_to_io_handler(&session::on_header_in,shared_from_this())); | |||
} | |||
void on_header_in(booster::system::error_code const &e) | |||
void on_header_in(booster::system::error_code const &e,size_t) | |||
{ | |||
if(e) { handle_error(e); return; } | |||
data_in_.clear(); | |||
data_in_.resize(hin_.size); | |||
if(hin_.size > 0) { | |||
socket_.async_read(io::buffer(data_in_), | |||
boost::bind(&session::on_data_in,shared_from_this(), | |||
_1)); | |||
mfunc_to_io_handler(&session::on_data_in,shared_from_this())); | |||
} | |||
else { | |||
on_data_in(e); | |||
on_data_in(e,0); | |||
} | |||
} | |||
@@ -241,7 +239,7 @@ public: | |||
BOOSTER_WARNING("cppcms_scale") << "Error on connection, fd=" << socket_.native() | |||
<<"; " << e.message(); | |||
} | |||
void on_data_in(booster::system::error_code const &e) | |||
void on_data_in(booster::system::error_code const &e,size_t ) | |||
{ | |||
if(e) { | |||
handle_error(e); | |||
@@ -289,10 +287,9 @@ public: | |||
packet += io::buffer(data_out_.c_str(),hout_.size); | |||
} | |||
socket_.async_write(packet, | |||
boost::bind(&session::on_data_out,shared_from_this(), | |||
_1)); | |||
mfunc_to_io_handler(&session::on_data_out,shared_from_this())); | |||
} | |||
void on_data_out(booster::system::error_code const &e) | |||
void on_data_out(booster::system::error_code const &e,size_t) | |||
{ | |||
if(e) { handle_error(e); return; } | |||
run(); | |||
@@ -315,7 +312,7 @@ class tcp_cache_service::server { | |||
s->run(); | |||
} | |||
else { | |||
s->socket_.get_io_service().post(boost::bind(&session::run,s)); | |||
s->socket_.get_io_service().post(mem_bind(&session::run,s)); | |||
} | |||
start_accept(); | |||
} | |||
@@ -333,7 +330,7 @@ class tcp_cache_service::server { | |||
void start_accept() | |||
{ | |||
booster::shared_ptr<session> s(new session(get_next_io_service(),cache_,sessions_)); | |||
acceptor_.async_accept(s->socket_,boost::bind(&server::on_accept,this,_1,s)); | |||
acceptor_.async_accept(s->socket_,mfunc_to_event_handler(&server::on_accept,this,s)); | |||
} | |||
public: | |||
server( std::vector<booster::shared_ptr<io::io_service> > &io, | |||
@@ -377,7 +374,7 @@ public: | |||
if(e) return; | |||
timer_.expires_from_now(booster::ptime::seconds(seconds_)); | |||
timer_.async_wait(boost::bind(&garbage_collector::async_run,this,_1)); | |||
timer_.async_wait(mfunc_to_event_handler(&garbage_collector::async_run,this)); | |||
io_->gc_job(); | |||
} | |||
@@ -405,31 +402,35 @@ private: | |||
}; | |||
static void thread_function(io::io_service *io) | |||
{ | |||
bool stop=false; | |||
try{ | |||
while(!stop) { | |||
try { | |||
io->run(); | |||
stop=true; | |||
} | |||
catch(cppcms::cppcms_error const &e) { | |||
// Not much to do... | |||
// Object will be destroyed automatically | |||
// Because it does not resubmit itself | |||
BOOSTER_ERROR("cppcms_scale") << "Error:" << e.what() << booster::trace(e); | |||
struct thread_functional { | |||
thread_functional(io::io_service *in) : io(in) {} | |||
io::io_service *io; | |||
void operator()() | |||
{ | |||
bool stop=false; | |||
try{ | |||
while(!stop) { | |||
try { | |||
io->run(); | |||
stop=true; | |||
} | |||
catch(cppcms::cppcms_error const &e) { | |||
// Not much to do... | |||
// Object will be destroyed automatically | |||
// Because it does not resubmit itself | |||
BOOSTER_ERROR("cppcms_scale") << "Error:" << e.what() << booster::trace(e); | |||
} | |||
} | |||
} | |||
catch(std::exception const &e) | |||
{ | |||
BOOSTER_ERROR("cppcms_scale") << "Fatal:" << e.what() << booster::trace(e); | |||
} | |||
catch(...){ | |||
BOOSTER_ERROR("cppcms_scale") << "Unknown exception" << std::endl; | |||
} | |||
} | |||
catch(std::exception const &e) | |||
{ | |||
BOOSTER_ERROR("cppcms_scale") << "Fatal:" << e.what() << booster::trace(e); | |||
} | |||
catch(...){ | |||
BOOSTER_ERROR("cppcms_scale") << "Unknown exception" << std::endl; | |||
} | |||
} | |||
}; | |||
struct tcp_cache_service::_data { | |||
std::vector<booster::shared_ptr<io::io_service> > io; | |||
@@ -462,12 +463,12 @@ tcp_cache_service::tcp_cache_service( booster::intrusive_ptr<base_cache> cache, | |||
#endif | |||
if(factory && factory->requires_gc()) { | |||
d->gc_runner.reset(new garbage_collector(factory,gc_timeout)); | |||
d->gc_thread.reset(new booster::thread(boost::bind(&garbage_collector::run,d->gc_runner))); | |||
d->gc_thread.reset(new booster::thread(mem_bind(&garbage_collector::run,d->gc_runner))); | |||
} | |||
for(int i=0;i<threads;i++){ | |||
booster::shared_ptr<booster::thread> thread; | |||
thread.reset(new booster::thread(boost::bind(thread_function,d->io[i].get()))); | |||
thread.reset(new booster::thread(thread_functional(d->io[i].get()))); | |||
d->threads.push_back(thread); | |||
} | |||
#ifndef CPPCMS_WIN32 | |||
@@ -13,13 +13,7 @@ | |||
#include <list> | |||
#include <vector> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/bind.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
#include <cppcms/mem_bind.h> | |||
#include <booster/shared_ptr.h> | |||
#include <booster/thread.h> | |||
@@ -62,7 +56,7 @@ namespace impl { | |||
pthread_sigmask(SIG_BLOCK,&set,&old); | |||
#endif | |||
for(int i=0;i<threads;i++) { | |||
workers_[i].reset(new booster::thread(boost::bind(&thread_pool::worker,this))); | |||
workers_[i].reset(new booster::thread(cppcms::util::mem_bind(&thread_pool::worker,this))); | |||
} | |||
#if defined(CPPCMS_POSIX) | |||