From 3b4016cb188509a9f1ce14763c88ae1ddcf437fa Mon Sep 17 00:00:00 2001 From: Artyom Beilis Date: Thu, 26 Nov 2015 15:46:46 +0000 Subject: [PATCH] Removed reference to Boost.Bind from all the code - get ready to get rid of cppcms_boost --- private/binder.h | 342 +++++++++++++++++++++++++++++++++++++++++++++ private/cgi_api.h | 2 +- private/prefork_acceptor.h | 8 +- src/application.cpp | 6 - src/cgi_api.cpp | 52 +++---- src/fastcgi_api.cpp | 88 ++++++------ src/forwarder.cpp | 34 ++--- src/hello_world.cpp | 21 ++- src/http_api.cpp | 29 ++-- src/http_context.cpp | 54 +++++-- src/scgi_api.cpp | 25 ++-- src/service.cpp | 29 ++-- src/session_pool.cpp | 18 +-- src/tcp_cache_server.cpp | 81 +++++------ src/thread_pool.cpp | 10 +- 15 files changed, 574 insertions(+), 225 deletions(-) create mode 100644 private/binder.h diff --git a/private/binder.h b/private/binder.h new file mode 100644 index 0000000..0a55803 --- /dev/null +++ b/private/binder.h @@ -0,0 +1,342 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) +// +// See accompanying file COPYING.TXT file for licensing details. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef CPPCMS_IMPL_BINDER +#define CPPCMS_IMPL_BINDER +#include +#include +namespace cppcms { +namespace impl { + + +// booster::aio::handler + +template +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 +booster::aio::handler::pointer_type mfunc_to_handler(void (C::*f)(),S s) +{ + return new handler_binder_p0(f,s); +} + +template +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 +booster::aio::handler::pointer_type mfunc_to_handler(void (C::*f)(P1),S s,P1in const &p1) +{ + return new handler_binder_p1(f,s,p1); +} + +template +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 +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(f,s,p1,p2); +} + + + + +// booster::aio::event_handler + +template +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 +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(f,s); +} + +template +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 +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(f,s,p1); +} + +template +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 +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(f,s,p1,p2); +} + + + +// booster::aio::io_handler + +template +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 +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(f,s); +} + +template +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 +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(f,s,p1); +} + +template +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 +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(f,s,p1,p2); +} + + +//// NON Member Functions + +// booster::aio::handler + +template +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 +booster::aio::handler::pointer_type func_to_handler(C const &f,P1 const &p1) +{ + return new handler_fbinder_p1(f,p1); +} + +template +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 +booster::aio::handler::pointer_type func_to_handler(C const &f,P1 const &p1,P2 const &p2) +{ + return new handler_fbinder_p2(f,p1,p2); +} + + + + +// booster::aio::event_handler + +template +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 +booster::aio::event_handler::pointer_type func_to_event_handler(C const &f,P1 const &p1) +{ + return new event_handler_fbinder_p1(f,p1); +} + +template +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 +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(f,p1,p2); +} + + + +// booster::aio::io_handler + +template +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 +booster::aio::io_handler::pointer_type func_to_io_handler(C f,P1 const &p1) +{ + return new io_handler_fbinder_p1(f,p1); +} + +template +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 +booster::aio::io_handler::pointer_type func_to_io_handler(C f,P1 const &p1,P2 const &p2) +{ + return new io_handler_fbinder_p2(f,p1,p2); +} + + + + + + + + + + +} // impl +} // cppcms + + +#endif diff --git a/private/cgi_api.h b/private/cgi_api.h index 87a02c0..069b474 100644 --- a/private/cgi_api.h +++ b/private/cgi_api.h @@ -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); diff --git a/private/prefork_acceptor.h b/private/prefork_acceptor.h index 8306964..c9e96e7 100644 --- a/private/prefork_acceptor.h +++ b/private/prefork_acceptor.h @@ -25,9 +25,7 @@ #include "cgi_api.h" -#include - -namespace boost = cppcms_boost; +#include 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;ipost(boost::bind(&cppcms::http::context::run,connections_[i])); + service_->post(cppcms::util::mem_bind(&cppcms::http::context::run,connections_[i])); } connections_.clear(); } // while loop diff --git a/src/application.cpp b/src/application.cpp index 9b80805..b17c86d 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -26,12 +26,6 @@ #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif namespace cppcms { diff --git a/src/cgi_api.cpp b/src/cgi_api.cpp index 7863bd1..fc047d8 100644 --- a/src/cgi_api.cpp +++ b/src/cgi_api.cpp @@ -22,12 +22,7 @@ #include #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif +#include "binder.h" #include #include @@ -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 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 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 "\r\n" "\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_); diff --git a/src/fastcgi_api.cpp b/src/fastcgi_api.cpp index a1b0cd1..16bcf4a 100644 --- a/src/fastcgi_api.cpp +++ b/src/fastcgi_api.cpp @@ -21,14 +21,8 @@ #include #include - -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif - +#include "binder.h" +#include #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 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(&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 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 const &cb, - void *ptr, - size_t expected_read_size) + std::pair inp) { + void *ptr = inp.first; + size_t expected_read_size = inp.second; cache_end_ += read_size; if(e) { cb(e,0); diff --git a/src/forwarder.cpp b/src/forwarder.cpp index 73357ae..455f9f7 100644 --- a/src/forwarder.cpp +++ b/src/forwarder.cpp @@ -25,19 +25,7 @@ #include #include "todec.h" - -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -# if defined(CPPCMS_WIN32) && _WIN32_WINNT <= 0x0501 && !defined(BOOST_ASIO_DISABLE_IOCP) -# define NO_CANCELIO -# endif -#else // Internal Boost -# include - 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())); } } diff --git a/src/hello_world.cpp b/src/hello_world.cpp index c7cdbee..8af098f 100644 --- a/src/hello_world.cpp +++ b/src/hello_world.cpp @@ -26,12 +26,6 @@ #include #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif #include #include "hello_world_view.h" @@ -61,6 +55,14 @@ public: response().finalize(); release_context()->async_complete_response(); } + struct binder { + chat *self; + booster::shared_ptr context; + void operator()() { + self->remove_context(context); + } + + }; void get(std::string no) { std::cerr<<"Get:"< context=release_context(); waiters_.insert(context); - context->async_on_peer_reset( - boost::bind( - &chat::remove_context, - booster::intrusive_ptr(this), - context)); + binder bd = { this, context }; + context->async_on_peer_reset(bd); } else { response().status(404); diff --git a/src/http_api.cpp b/src/http_api.cpp index f2af1ea..feb4468 100644 --- a/src/http_api.cpp +++ b/src/http_api.cpp @@ -21,10 +21,9 @@ #include #include #include -#include #include -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 diff --git a/src/http_context.cpp b/src/http_context.cpp index 2d5c87f..068198b 100644 --- a/src/http_context.cpp +++ b/src/http_context.cpp @@ -24,14 +24,7 @@ #include "cached_settings.h" #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - 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 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,std::string,bool); + booster::intrusive_ptr 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 ctx; + void operator()() { + ctx->run(); + } + }; +} + void context::complete_response() { response().finalize(); if(conn_->is_reuseable()) { booster::shared_ptr 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(); diff --git a/src/scgi_api.cpp b/src/scgi_api.cpp index a53eb05..ee2302b 100644 --- a/src/scgi_api.cpp +++ b/src/scgi_api.cpp @@ -15,15 +15,11 @@ #include #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif #include #include +#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_; } diff --git a/src/service.cpp b/src/service.cpp index 42ad09b..7830741 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "cgi_acceptor.h" #ifndef CPPCMS_WIN32 #include "prefork_acceptor.h" @@ -73,12 +74,6 @@ #include #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - 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 argv(argc+1,static_cast(0)); diff --git a/src/session_pool.cpp b/src/session_pool.cpp index 9e3a388..2de034c 100644 --- a/src/session_pool.cpp +++ b/src/session_pool.cpp @@ -19,8 +19,7 @@ #include #include #include -#include -namespace boost = cppcms_boost; +#include #include "aes_encryptor.h" @@ -38,6 +37,7 @@ namespace boost = cppcms_boost; #include #include #include +#include #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 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 job(new gc_job(service_,frequency,this)); - job->async_run(); + job->async_run(booster::system::error_code()); } } } diff --git a/src/tcp_cache_server.cpp b/src/tcp_cache_server.cpp index b9b1ef7..b977aa5 100644 --- a/src/tcp_cache_server.cpp +++ b/src/tcp_cache_server.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,8 @@ #include #include #include +#include +#include "binder.h" #include #include #include @@ -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 { @@ -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 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 > &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 > io; @@ -462,12 +463,12 @@ tcp_cache_service::tcp_cache_service( booster::intrusive_ptr 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 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 diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 5cb9fd6..e46f76b 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -13,13 +13,7 @@ #include #include #include -#ifdef CPPCMS_USE_EXTERNAL_BOOST -# include -#else // Internal Boost -# include - namespace boost = cppcms_boost; -#endif - +#include #include #include @@ -62,7 +56,7 @@ namespace impl { pthread_sigmask(SIG_BLOCK,&set,&old); #endif for(int i=0;i