@@ -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 set_error(ehandler const &h,std::string s); | ||||
void on_headers_read(booster::system::error_code const &e,http::context *,ehandler const &h); | 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 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 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_eof(callback const &on_eof); | ||||
void handle_http_error(int code,http::context *context,ehandler const &h); | void handle_http_error(int code,http::context *context,ehandler const &h); | ||||
@@ -25,9 +25,7 @@ | |||||
#include "cgi_api.h" | #include "cgi_api.h" | ||||
#include <cppcms_boost/bind.hpp> | |||||
namespace boost = cppcms_boost; | |||||
#include <cppcms/mem_bind.hpp> | |||||
namespace cppcms { | namespace cppcms { | ||||
namespace impl { | namespace impl { | ||||
@@ -70,7 +68,7 @@ public: | |||||
} | } | ||||
read_interrupter_=fds[0]; | read_interrupter_=fds[0]; | ||||
write_interrupter_=fds[1]; | 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: | private: | ||||
void stop() | void stop() | ||||
@@ -185,7 +183,7 @@ private: | |||||
} | } | ||||
for(unsigned i=0;i<connections_.size();i++) { | 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(); | connections_.clear(); | ||||
} // while loop | } // while loop | ||||
@@ -26,12 +26,6 @@ | |||||
#include <booster/locale/message.h> | #include <booster/locale/message.h> | ||||
#include <cppcms/config.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 { | namespace cppcms { | ||||
@@ -22,12 +22,7 @@ | |||||
#include <scgi_header.h> | #include <scgi_header.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <cppcms/config.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/log.h> | ||||
#include <booster/aio/endpoint.h> | #include <booster/aio/endpoint.h> | ||||
@@ -55,7 +50,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||||
} | } | ||||
void async_run() | 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: | private: | ||||
void on_connected(booster::system::error_code const &e) | 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); | header_ = make_scgi_header(conn_->getenv(),0); | ||||
scgi_.async_write( | scgi_.async_write( | ||||
booster::aio::buffer(header_), | 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) | 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_); | post_.resize(content_length_); | ||||
} | } | ||||
conn_->async_read_some(&post_.front(),post_.size(), | 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 { | else { | ||||
response_.swap(post_); | response_.swap(post_); | ||||
@@ -103,7 +98,7 @@ namespace cppcms { namespace impl { namespace cgi { | |||||
conn_->on_async_read_complete(); | conn_->on_async_read_complete(); | ||||
scgi_.async_write( | scgi_.async_write( | ||||
booster::aio::buffer(&post_.front(),len), | 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) | 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() | 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_), | 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) | void on_response_read(booster::system::error_code const &e,size_t len) | ||||
{ | { | ||||
if(e) { | 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; | return; | ||||
} | } | ||||
else { | 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) | void on_response_written(booster::system::error_code const &e) | ||||
{ | { | ||||
if(e) { cleanup(); return; } | if(e) { cleanup(); return; } | ||||
scgi_.async_read_some(booster::aio::buffer(response_), | 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() | void cleanup() | ||||
@@ -142,6 +137,10 @@ namespace cppcms { namespace impl { namespace cgi { | |||||
scgi_.shutdown(booster::aio::stream_socket::shut_rdwr,e); | scgi_.shutdown(booster::aio::stream_socket::shut_rdwr,e); | ||||
scgi_.close(e); | scgi_.close(e); | ||||
} | } | ||||
void cleanup(booster::system::error_code const &) | |||||
{ | |||||
cleanup(); | |||||
} | |||||
booster::shared_ptr<connection> conn_; | booster::shared_ptr<connection> conn_; | ||||
booster::aio::stream_socket scgi_; | booster::aio::stream_socket scgi_; | ||||
@@ -186,10 +185,10 @@ void connection::async_prepare_request( http::context *context, | |||||
socket().set_non_blocking(true,e); | socket().set_non_blocking(true,e); | ||||
if(e) { | if(e) { | ||||
BOOSTER_WARNING("cppcms") << "Failed to set nonblocking mode in socket " << e.message(); | 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; | 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) | 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) | 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) | 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" | "</body>\r\n" | ||||
"</html>\r\n"; | "</html>\r\n"; | ||||
async_write(booster::aio::buffer(async_chunk_),true, | async_write(booster::aio::buffer(async_chunk_),true, | ||||
boost::bind( | |||||
mfunc_to_event_handler( | |||||
&connection::handle_http_error_eof, | &connection::handle_http_error_eof, | ||||
self(), | self(), | ||||
_1, | |||||
code, | code, | ||||
h)); | h)); | ||||
} | } | ||||
@@ -331,10 +329,8 @@ void connection::load_content(booster::system::error_code const &e,http::context | |||||
content_.clear(); | content_.clear(); | ||||
content_.resize(8192); | content_.resize(8192); | ||||
async_read_some(&content_.front(),content_.size(), | async_read_some(&content_.front(),content_.size(), | ||||
boost::bind(&connection::on_some_multipart_read, | |||||
mfunc_to_io_handler(&connection::on_some_multipart_read, | |||||
self(), | self(), | ||||
_1, | |||||
_2, | |||||
context, | context, | ||||
h)); | h)); | ||||
} | } | ||||
@@ -350,11 +346,11 @@ void connection::load_content(booster::system::error_code const &e,http::context | |||||
content_.resize(content_length,0); | content_.resize(content_length,0); | ||||
async_read( &content_.front(), | async_read( &content_.front(), | ||||
content_.size(), | 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 { | 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 { | else { | ||||
async_read_some(&content_.front(),content_.size(), | async_read_some(&content_.front(),content_.size(), | ||||
boost::bind(&connection::on_some_multipart_read, | |||||
mfunc_to_io_handler(&connection::on_some_multipart_read, | |||||
self(), | self(), | ||||
_1, | |||||
_2, | |||||
context, | context, | ||||
h)); | 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; } | if(e) { set_error(h,e.message()); return; } | ||||
context->request().set_post_data(content_); | context->request().set_post_data(content_); | ||||
@@ -21,14 +21,8 @@ | |||||
#include <cppcms/config.h> | #include <cppcms/config.h> | ||||
#include <booster/aio/buffer.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" | #include "cached_settings.h" | ||||
@@ -76,16 +70,13 @@ namespace cgi { | |||||
virtual void async_read_headers(handler const &h) | virtual void async_read_headers(handler const &h) | ||||
{ | { | ||||
reset_all(); | 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) | virtual void async_read_some(void *p,size_t s,io_handler const &h) | ||||
{ | { | ||||
if(read_length_ == content_length_) { | 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; | return; | ||||
} | } | ||||
if(body_ptr_ < body_.size()) { | if(body_ptr_ < body_.size()) { | ||||
@@ -102,29 +93,28 @@ namespace cgi { | |||||
} | } | ||||
if(read_length_ >= content_length_) { | if(read_length_ >= content_length_) { | ||||
async_read_record(boost::bind( | |||||
async_read_record(mfunc_to_event_handler( | |||||
&fastcgi::on_read_stdin_eof_expected, | &fastcgi::on_read_stdin_eof_expected, | ||||
self(), | self(), | ||||
_1, | |||||
h, | h, | ||||
s)); | s)); | ||||
return; | 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; | return; | ||||
} | } | ||||
else { | else { | ||||
async_read_record(boost::bind( | |||||
async_read_record(mfunc_to_event_handler( | |||||
&fastcgi::on_some_input_recieved, | &fastcgi::on_some_input_recieved, | ||||
self(), | self(), | ||||
_1,h,p,s)); | |||||
h,std::make_pair(p,s))); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
virtual void on_async_write_start(){} | virtual void on_async_write_start(){} | ||||
virtual void on_async_write_progress(bool){} | virtual void on_async_write_progress(bool){} | ||||
private: | 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(e) { h(e,0); return; } | ||||
if( header_.type!=fcgi_stdin | if( header_.type!=fcgi_stdin | ||||
@@ -134,7 +124,7 @@ namespace cgi { | |||||
h(booster::system::error_code(errc::protocol_violation,cppcms_category),0); | h(booster::system::error_code(errc::protocol_violation,cppcms_category),0); | ||||
return; | 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) | 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; | 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 | // This is not really correct because server may try | ||||
// to multiplex or ask control... But meanwhile it is good enough | // to multiplex or ask control... But meanwhile it is good enough | ||||
virtual void async_read_eof(callback const &h) | virtual void async_read_eof(callback const &h) | ||||
{ | { | ||||
eof_callback_ = true; | eof_callback_ = true; | ||||
static char a; | static char a; | ||||
async_read_from_socket(&a,1,boost::bind(h)); | |||||
async_read_from_socket(&a,1,io_handler_to_handler(h)); | |||||
} | } | ||||
private: | private: | ||||
@@ -419,9 +427,8 @@ namespace cgi { | |||||
else if(name=="FCGI_MPXS_CONNS") | else if(name=="FCGI_MPXS_CONNS") | ||||
add_pair(name,"0"); | 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(), | self(), | ||||
_1, | |||||
h)); | h)); | ||||
} | } | ||||
else if(header_.type!=fcgi_begin_request) { | 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()); | fcgi_end_request_body *body=reinterpret_cast<fcgi_end_request_body*>(&body_.front()); | ||||
body->protocol_status=fcgi_unknown_role; | body->protocol_status=fcgi_unknown_role; | ||||
body->to_net(); | 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(), | self(), | ||||
_1, | |||||
h)); | h)); | ||||
return; | return; | ||||
} | } | ||||
@@ -456,7 +462,7 @@ namespace cgi { | |||||
params_record_expected(booster::system::error_code(),h); | params_record_expected(booster::system::error_code(),h); | ||||
} | } | ||||
else { | 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; | continue; | ||||
} | } | ||||
else { | else { | ||||
async_read_record(boost::bind( &fastcgi::params_record_expected, | |||||
async_read_record(mfunc_to_event_handler(&fastcgi::params_record_expected, | |||||
self(), | self(), | ||||
_1, | |||||
h)); | h)); | ||||
} | } | ||||
} | } | ||||
@@ -582,10 +587,9 @@ namespace cgi { | |||||
stdin_eof_expected(booster::system::error_code(),h); | stdin_eof_expected(booster::system::error_code(),h); | ||||
} | } | ||||
else { | else { | ||||
async_read_record(boost::bind( | |||||
async_read_record(mfunc_to_event_handler( | |||||
&fastcgi::stdin_eof_expected, | &fastcgi::stdin_eof_expected, | ||||
self(), | self(), | ||||
_1, | |||||
h)); | h)); | ||||
} | } | ||||
return; | return; | ||||
@@ -622,7 +626,7 @@ namespace cgi { | |||||
+ io::buffer(body_); | + io::buffer(body_); | ||||
header_.to_net(); | 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) | void async_read_record(handler const &h) | ||||
{ | { | ||||
async_read_from_socket(&header_,sizeof(header_), | async_read_from_socket(&header_,sizeof(header_), | ||||
boost::bind( &fastcgi::on_header_read, | |||||
mfunc_to_io_handler( | |||||
&fastcgi::on_header_read, | |||||
self(), | self(), | ||||
_1, | |||||
h)); | 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; } | if(e) { h(e); return; } | ||||
header_.to_host(); | header_.to_host(); | ||||
@@ -787,12 +791,12 @@ namespace cgi { | |||||
cache_start_+=n; | 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) { | if(cache_end_ - cache_start_ >=n) { | ||||
memcpy(ptr,&cache_[cache_start_],n); | memcpy(ptr,&cache_[cache_start_],n); | ||||
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; | return; | ||||
} | } | ||||
if(cache_start_ == cache_end_) { | if(cache_start_ == cache_end_) { | ||||
@@ -811,21 +815,19 @@ namespace cgi { | |||||
socket_.async_read_some( | socket_.async_read_some( | ||||
booster::aio::buffer(&cache_[cache_end_],cache_.size() - cache_end_), | booster::aio::buffer(&cache_[cache_end_],cache_.size() - cache_end_), | ||||
boost::bind( | |||||
mfunc_to_io_handler( | |||||
&fastcgi::on_some_read_from_socket, | &fastcgi::on_some_read_from_socket, | ||||
self(), | self(), | ||||
_1, | |||||
_2, | |||||
cb, | cb, | ||||
ptr, | |||||
n)); | |||||
std::make_pair(ptr,n))); | |||||
} | } | ||||
void on_some_read_from_socket( booster::system::error_code const &e, | void on_some_read_from_socket( booster::system::error_code const &e, | ||||
size_t read_size, | size_t read_size, | ||||
booster::callback<void(booster::system::error_code const &e,size_t read)> const &cb, | 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; | cache_end_ += read_size; | ||||
if(e) { | if(e) { | ||||
cb(e,0); | cb(e,0); | ||||
@@ -25,19 +25,7 @@ | |||||
#include <scgi_header.h> | #include <scgi_header.h> | ||||
#include "todec.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; | namespace io = booster::aio; | ||||
@@ -58,13 +46,11 @@ namespace cppcms { | |||||
io::endpoint ep(ip_,port_); | io::endpoint ep(ip_,port_); | ||||
socket_.open(ep.family()); | socket_.open(ep.family()); | ||||
socket_.async_connect(ep, | 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: | private: | ||||
void on_connected(booster::system::error_code e) | |||||
void on_connected(booster::system::error_code const &e) | |||||
{ | { | ||||
if(e) { | if(e) { | ||||
connection_->response().make_error_response(500); | connection_->response().make_error_response(500); | ||||
@@ -73,10 +59,10 @@ namespace cppcms { | |||||
} | } | ||||
socket_.async_write( | socket_.async_write( | ||||
io::buffer(data_), | 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) { | if(e) { | ||||
connection_->response().make_error_response(500); | 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); | connection_->response().io_mode(http::response::asynchronous_raw); | ||||
input_.resize(4096); | input_.resize(4096); | ||||
socket_.async_read_some(io::buffer(input_), | 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 { | else { | ||||
socket_.async_read_some(io::buffer(input_), | 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 <set> | ||||
#include <cppcms/config.h> | #include <cppcms/config.h> | ||||
#include <cppcms/mem_bind.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 <fstream> | ||||
#include "hello_world_view.h" | #include "hello_world_view.h" | ||||
@@ -61,6 +55,14 @@ public: | |||||
response().finalize(); | response().finalize(); | ||||
release_context()->async_complete_response(); | 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) | void get(std::string no) | ||||
{ | { | ||||
std::cerr<<"Get:"<<waiters_.size()<<std::endl; | std::cerr<<"Get:"<<waiters_.size()<<std::endl; | ||||
@@ -73,11 +75,8 @@ public: | |||||
else if(pos == messages_.size()) { | else if(pos == messages_.size()) { | ||||
booster::shared_ptr<cppcms::http::context> context=release_context(); | booster::shared_ptr<cppcms::http::context> context=release_context(); | ||||
waiters_.insert(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 { | else { | ||||
response().status(404); | response().status(404); | ||||
@@ -21,10 +21,9 @@ | |||||
#include <list> | #include <list> | ||||
#include <sstream> | #include <sstream> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cppcms_boost/bind.hpp> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
namespace boost = cppcms_boost; | |||||
#include "binder.h" | |||||
// for testing only | // for testing only | ||||
//#define CPPCMS_NO_SO_SNDTIMO | //#define CPPCMS_NO_SO_SNDTIMO | ||||
@@ -193,7 +192,7 @@ namespace cgi { | |||||
void async_read_some_headers(handler const &h) | 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(); | update_time(); | ||||
} | } | ||||
virtual void async_read_headers(handler const &h) | virtual void async_read_headers(handler const &h) | ||||
@@ -222,17 +221,16 @@ namespace cgi { | |||||
n = socket_.read_some(booster::aio::buffer(input_body_),e); | n = socket_.read_some(booster::aio::buffer(input_body_),e); | ||||
total_read_+=n; | total_read_+=n; | ||||
if(total_read_ > 16384) { | |||||
h(booster::system::error_code(errc::protocol_violation,cppcms_category)); | |||||
return; | |||||
} | |||||
input_body_.resize(n); | input_body_.resize(n); | ||||
for(;;) { | for(;;) { | ||||
using ::cppcms::http::impl::parser; | using ::cppcms::http::impl::parser; | ||||
switch(input_parser_.step()) { | switch(input_parser_.step()) { | ||||
case parser::more_data: | case parser::more_data: | ||||
if(total_read_ > 16384) { | |||||
h(booster::system::error_code(errc::protocol_violation,cppcms_category)); | |||||
return; | |||||
} | |||||
// Assuming body_ptr == body.size() | // Assuming body_ptr == body.size() | ||||
async_read_some_headers(h); | async_read_some_headers(h); | ||||
return; | return; | ||||
@@ -304,7 +302,7 @@ namespace cgi { | |||||
input_body_.clear(); | input_body_.clear(); | ||||
input_body_ptr_=0; | 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; | return; | ||||
} | } | ||||
if(input_body_.capacity()!=0) { | if(input_body_.capacity()!=0) { | ||||
@@ -416,11 +414,16 @@ namespace cgi { | |||||
socket_.shutdown(io::stream_socket::shut_rdwr,e); | socket_.shutdown(io::stream_socket::shut_rdwr,e); | ||||
socket_.close(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) | virtual void async_read_eof(callback const &h) | ||||
{ | { | ||||
watchdog_->add(self()); | watchdog_->add(self()); | ||||
static char a; | 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() | void on_async_write_start() | ||||
@@ -611,9 +614,9 @@ namespace cgi { | |||||
void error_response(char const *message,handler const &h) | void error_response(char const *message,handler const &h) | ||||
{ | { | ||||
socket_.async_write(io::buffer(message,strlen(message)), | 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) { | if(e) { | ||||
h(e); | h(e); | ||||
@@ -739,7 +742,7 @@ namespace cgi { | |||||
} | } | ||||
timer_.expires_from_now(booster::ptime(1)); | 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 | http *http_creator::operator()(cppcms::service &srv) const | ||||
@@ -24,14 +24,7 @@ | |||||
#include "cached_settings.h" | #include "cached_settings.h" | ||||
#include <cppcms/config.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 { | 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() | 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) | void context::on_request_ready(bool error) | ||||
@@ -109,16 +123,30 @@ void context::on_request_ready(bool error) | |||||
dispatch(app,matched,false); | dispatch(app,matched,false); | ||||
} | } | ||||
else { | 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() | void context::complete_response() | ||||
{ | { | ||||
response().finalize(); | response().finalize(); | ||||
if(conn_->is_reuseable()) { | if(conn_->is_reuseable()) { | ||||
booster::shared_ptr<context> cont(new context(conn_)); | booster::shared_ptr<context> cont(new context(conn_)); | ||||
service().post(boost::bind(&context::run,cont)); | |||||
run_ctx rn = { cont }; | |||||
service().post(rn); | |||||
} | } | ||||
conn_.reset(); | conn_.reset(); | ||||
} | } | ||||
@@ -180,14 +208,16 @@ void context::async_flush_output(context::handler const &h) | |||||
h); | h); | ||||
} | } | ||||
void context::async_complete_response() | void context::async_complete_response() | ||||
{ | { | ||||
response().finalize(); | response().finalize(); | ||||
if(response().io_mode() == http::response::asynchronous || response().io_mode() == http::response::asynchronous_raw) { | 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( | conn_->async_write_response( | ||||
response(), | response(), | ||||
true, | true, | ||||
boost::bind(&context::try_restart,self(),_1)); | |||||
cb); | |||||
return; | return; | ||||
} | } | ||||
complete_response(); | complete_response(); | ||||
@@ -15,15 +15,11 @@ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <cppcms/config.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 <booster/aio/buffer.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "binder.h" | |||||
namespace io = booster::aio; | namespace io = booster::aio; | ||||
namespace cppcms { | namespace cppcms { | ||||
@@ -52,10 +48,9 @@ namespace cgi { | |||||
buffer_.resize(16); | buffer_.resize(16); | ||||
socket_.async_read( | socket_.async_read( | ||||
io::buffer(buffer_), | io::buffer(buffer_), | ||||
boost::bind( | |||||
mfunc_to_io_handler( | |||||
&scgi::on_first_read, | &scgi::on_first_read, | ||||
self(), | self(), | ||||
_1,_2, | |||||
h)); | h)); | ||||
} | } | ||||
@@ -86,12 +81,12 @@ namespace cgi { | |||||
} | } | ||||
socket_.async_read( | socket_.async_read( | ||||
io::buffer(&buffer_[size],buffer_.size() - size), | io::buffer(&buffer_[size],buffer_.size() - size), | ||||
boost::bind( &scgi::on_headers_chunk_read, | |||||
mfunc_to_io_handler( | |||||
&scgi::on_headers_chunk_read, | |||||
self(), | self(), | ||||
_1, | |||||
h)); | 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(e) { h(e); return; } | ||||
if(buffer_.back()!=',') { | if(buffer_.back()!=',') { | ||||
@@ -145,11 +140,17 @@ namespace cgi { | |||||
socket_.close(e); | 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) | virtual void async_read_eof(callback const &h) | ||||
{ | { | ||||
eof_callback_ = true; | eof_callback_ = true; | ||||
static char a; | 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_; } | virtual booster::aio::stream_socket &socket() { return socket_; } | ||||
@@ -31,6 +31,7 @@ | |||||
#include <cppcms/cppcms_error.h> | #include <cppcms/cppcms_error.h> | ||||
#include <cppcms/mount_point.h> | #include <cppcms/mount_point.h> | ||||
#include <cppcms/forwarder.h> | #include <cppcms/forwarder.h> | ||||
#include <cppcms/mem_bind.h> | |||||
#include "cgi_acceptor.h" | #include "cgi_acceptor.h" | ||||
#ifndef CPPCMS_WIN32 | #ifndef CPPCMS_WIN32 | ||||
#include "prefork_acceptor.h" | #include "prefork_acceptor.h" | ||||
@@ -73,12 +74,6 @@ | |||||
#include <booster/nowide/fstream.h> | #include <booster/nowide/fstream.h> | ||||
#include <booster/thread.h> | #include <booster/thread.h> | ||||
#include <cppcms/config.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 | #ifndef CPPCMS_WIN32 | ||||
#include "daemonize.h" | #include "daemonize.h" | ||||
@@ -380,14 +375,25 @@ namespace { | |||||
} // anon | } // 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() | void service::setup_exit_handling() | ||||
{ | { | ||||
io::socket_pair(*impl_->sig_,*impl_->breaker_); | io::socket_pair(*impl_->sig_,*impl_->breaker_); | ||||
static char c; | 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(); | impl_->notification_socket_=impl_->sig_->native(); | ||||
@@ -532,9 +538,10 @@ void service::win_service_exec() | |||||
void service::run_win_service() | 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(); | int argc=impl_->args_.size(); | ||||
std::vector<char*> argv(argc+1,static_cast<char*>(0)); | std::vector<char*> argv(argc+1,static_cast<char*>(0)); | ||||
@@ -19,8 +19,7 @@ | |||||
#include <booster/shared_object.h> | #include <booster/shared_object.h> | ||||
#include <booster/enable_shared_from_this.h> | #include <booster/enable_shared_from_this.h> | ||||
#include <cppcms/config.h> | #include <cppcms/config.h> | ||||
#include <cppcms_boost/bind.hpp> | |||||
namespace boost = cppcms_boost; | |||||
#include <cppcms/mem_bind.h> | |||||
#include "aes_encryptor.h" | #include "aes_encryptor.h" | ||||
@@ -38,6 +37,7 @@ namespace boost = cppcms_boost; | |||||
#include <booster/aio/deadline_timer.h> | #include <booster/aio/deadline_timer.h> | ||||
#include <booster/callback.h> | #include <booster/callback.h> | ||||
#include <booster/posix_time.h> | #include <booster/posix_time.h> | ||||
#include <booster/system_error.h> | |||||
#include "cached_settings.h" | #include "cached_settings.h" | ||||
@@ -130,18 +130,20 @@ public: | |||||
pool_(pool) | 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: | private: | ||||
void gc() const | |||||
void gc() | |||||
{ | { | ||||
booster::ptime start = booster::ptime::now(); | booster::ptime start = booster::ptime::now(); | ||||
booster::ptime restart = start + booster::ptime::from_number(freq_); | booster::ptime restart = start + booster::ptime::from_number(freq_); | ||||
pool_->backend_->gc(); | pool_->backend_->gc(); | ||||
timer_->expires_at(restart); | 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_; | booster::shared_ptr<booster::aio::deadline_timer> timer_; | ||||
service *service_; | service *service_; | ||||
@@ -318,7 +320,7 @@ void session_pool::init() | |||||
throw cppcms_error("Unknown location"); | throw cppcms_error("Unknown location"); | ||||
if(service_) | 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) : | session_pool::session_pool(service &srv) : | ||||
@@ -342,7 +344,7 @@ void session_pool::after_fork() | |||||
double frequency = service_->settings().get("session.gc",0.0); | double frequency = service_->settings().get("session.gc",0.0); | ||||
if(frequency > 0) { | if(frequency > 0) { | ||||
booster::shared_ptr<gc_job> job(new gc_job(service_,frequency,this)); | 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/cppcms_error.h> | ||||
#include <cppcms/config.h> | #include <cppcms/config.h> | ||||
#include <cppcms/session_storage.h> | #include <cppcms/session_storage.h> | ||||
#include <cppcms_boost/bind.hpp> | |||||
#include <booster/shared_ptr.h> | #include <booster/shared_ptr.h> | ||||
#include <booster/enable_shared_from_this.h> | #include <booster/enable_shared_from_this.h> | ||||
#include <booster/thread.h> | #include <booster/thread.h> | ||||
@@ -29,6 +28,8 @@ | |||||
#include <booster/aio/endpoint.h> | #include <booster/aio/endpoint.h> | ||||
#include <booster/aio/buffer.h> | #include <booster/aio/buffer.h> | ||||
#include <booster/aio/deadline_timer.h> | #include <booster/aio/deadline_timer.h> | ||||
#include <cppcms/mem_bind.h> | |||||
#include "binder.h" | |||||
#include <booster/log.h> | #include <booster/log.h> | ||||
#include <time.h> | #include <time.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
@@ -38,12 +39,11 @@ | |||||
#include "tcp_cache_server.h" | #include "tcp_cache_server.h" | ||||
namespace boost = cppcms_boost; | |||||
namespace cppcms { | namespace cppcms { | ||||
namespace impl { | namespace impl { | ||||
using cppcms::util::mem_bind; | |||||
namespace io = booster::aio; | namespace io = booster::aio; | ||||
class tcp_cache_service::session : public booster::enable_shared_from_this<tcp_cache_service::session> { | class tcp_cache_service::session : public booster::enable_shared_from_this<tcp_cache_service::session> { | ||||
@@ -72,21 +72,19 @@ public: | |||||
void run() | void run() | ||||
{ | { | ||||
socket_.async_read(io::buffer(&hin_,sizeof(hin_)), | 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; } | if(e) { handle_error(e); return; } | ||||
data_in_.clear(); | data_in_.clear(); | ||||
data_in_.resize(hin_.size); | data_in_.resize(hin_.size); | ||||
if(hin_.size > 0) { | if(hin_.size > 0) { | ||||
socket_.async_read(io::buffer(data_in_), | 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 { | 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() | BOOSTER_WARNING("cppcms_scale") << "Error on connection, fd=" << socket_.native() | ||||
<<"; " << e.message(); | <<"; " << 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) { | if(e) { | ||||
handle_error(e); | handle_error(e); | ||||
@@ -289,10 +287,9 @@ public: | |||||
packet += io::buffer(data_out_.c_str(),hout_.size); | packet += io::buffer(data_out_.c_str(),hout_.size); | ||||
} | } | ||||
socket_.async_write(packet, | 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; } | if(e) { handle_error(e); return; } | ||||
run(); | run(); | ||||
@@ -315,7 +312,7 @@ class tcp_cache_service::server { | |||||
s->run(); | s->run(); | ||||
} | } | ||||
else { | 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(); | start_accept(); | ||||
} | } | ||||
@@ -333,7 +330,7 @@ class tcp_cache_service::server { | |||||
void start_accept() | void start_accept() | ||||
{ | { | ||||
booster::shared_ptr<session> s(new session(get_next_io_service(),cache_,sessions_)); | 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: | public: | ||||
server( std::vector<booster::shared_ptr<io::io_service> > &io, | server( std::vector<booster::shared_ptr<io::io_service> > &io, | ||||
@@ -377,7 +374,7 @@ public: | |||||
if(e) return; | if(e) return; | ||||
timer_.expires_from_now(booster::ptime::seconds(seconds_)); | 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(); | 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 { | struct tcp_cache_service::_data { | ||||
std::vector<booster::shared_ptr<io::io_service> > io; | 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 | #endif | ||||
if(factory && factory->requires_gc()) { | if(factory && factory->requires_gc()) { | ||||
d->gc_runner.reset(new garbage_collector(factory,gc_timeout)); | 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++){ | for(int i=0;i<threads;i++){ | ||||
booster::shared_ptr<booster::thread> thread; | 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); | d->threads.push_back(thread); | ||||
} | } | ||||
#ifndef CPPCMS_WIN32 | #ifndef CPPCMS_WIN32 | ||||
@@ -13,13 +13,7 @@ | |||||
#include <list> | #include <list> | ||||
#include <vector> | #include <vector> | ||||
#include <cppcms/config.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 <cppcms/mem_bind.h> | |||||
#include <booster/shared_ptr.h> | #include <booster/shared_ptr.h> | ||||
#include <booster/thread.h> | #include <booster/thread.h> | ||||
@@ -62,7 +56,7 @@ namespace impl { | |||||
pthread_sigmask(SIG_BLOCK,&set,&old); | pthread_sigmask(SIG_BLOCK,&set,&old); | ||||
#endif | #endif | ||||
for(int i=0;i<threads;i++) { | 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) | #if defined(CPPCMS_POSIX) | ||||