ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

421 lines
10 KiB

  1. Index: proc_acceptor.cpp
  2. ===================================================================
  3. --- proc_acceptor.cpp (revision 1153)
  4. +++ proc_acceptor.cpp (working copy)
  5. @@ -1,5 +1,6 @@
  6. #define CPPCMS_SOURCE
  7. #include "proc_acceptor.h"
  8. +#include <iostream>
  9. namespace cppcms { namespace impl {
  10. process_shared_acceptor::process_shared_acceptor(cppcms::service &srv)
  11. @@ -12,15 +13,30 @@
  12. service_=&srv.impl().get_io_service();
  13. srv.after_fork(boost::bind(&process_shared_acceptor::on_fork,this));
  14. }
  15. +
  16. + void process_shared_acceptor::start()
  17. + {
  18. + worker_.reset(new boost::thread(boost::bind(&process_shared_acceptor::run,this)));
  19. + }
  20. +
  21. + void process_shared_acceptor::stop()
  22. + {
  23. + stop_ = true;
  24. + wake();
  25. + worker_->join();
  26. + }
  27. void process_shared_acceptor::on_fork()
  28. {
  29. int fds[2];
  30. - pipe(fds);
  31. + if(::pipe(fds) < 0) {
  32. + throw cppcms_error(errno,"Creation of pipe failed");
  33. + }
  34. break_fd_=fds[0];
  35. wake_fd_=fds[1];
  36. max_1_=std::max(break_fd_,wake_fd_)+1;
  37. FD_SET(break_fd_,&wait_set);
  38. + start();
  39. }
  40. void process_shared_acceptor::wake()
  41. {
  42. @@ -32,6 +48,26 @@
  43. }
  44. }
  45. + struct assigner_and_caller {
  46. + function<void(int)> assigner;
  47. + function<void(boost::system::error_code const &e)> callback;
  48. + int fd;
  49. + boost::system::error_code e;
  50. + void operator()()
  51. + {
  52. + std::cout << "Assigning and calling" << std::endl;
  53. + try {
  54. + if(!assigner.empty())
  55. + assigner(fd);
  56. + callback(e);
  57. + }
  58. + catch(std::exception const &e)
  59. + {
  60. + std::cerr << "Assigning and calling failed " << e.what() << std::endl;
  61. + }
  62. + }
  63. + };
  64. +
  65. bool process_shared_acceptor::run_one()
  66. {
  67. fd_set rd;
  68. @@ -42,7 +78,9 @@
  69. int n;
  70. {
  71. mutex::guard guard(process_mutex_);
  72. + std::cout << "Selecting " << getpid() << std::endl;
  73. n=::select(max_1_,&rd,0,0,0);
  74. + std::cout << "Selected " << n << std::endl;
  75. if(n < 0 && errno==EINTR)
  76. return true;
  77. if(n < 0)
  78. @@ -63,19 +101,22 @@
  79. int fd=::accept(afd,0,0);
  80. int err=errno;
  81. + std::cout << "Accepted " << afd << " as " << fd << " in " << getpid() <<std::endl;
  82. +
  83. thread_guard tguard(thread_mutex_);
  84. - boost::system::error_code e;
  85. - if(fd > 0) {
  86. - assigners_[afd](fd);
  87. - assigners_[afd]=assign_function();
  88. + assigner_and_caller anc;
  89. + if(fd >= 0) {
  90. + anc.assigner.swap(assigners_[afd]);
  91. + anc.fd=fd;
  92. }
  93. else {
  94. - e=boost::system::error_code(err,boost::system::errno_ecat);
  95. + anc.e=boost::system::error_code(err,boost::system::errno_ecat);
  96. }
  97. - service_->post(boost::bind(callbacks_[afd],e));
  98. - callbacks_[afd]=on_accept_function();
  99. + anc.callback.swap(callbacks_[afd]);
  100. FD_CLR(afd,&wait_set);
  101. + std::cout << "Posting " << std::endl;
  102. + service_->post(anc);
  103. }
  104. }
  105. }
  106. @@ -83,8 +124,10 @@
  107. }
  108. void process_shared_acceptor::run()
  109. {
  110. + std::cout << "Running " << getpid() << std::endl;
  111. while(run_one())
  112. ;
  113. + std::cout << "Done " << getpid() << std::endl;
  114. }
  115. process_shared_acceptor::~process_shared_acceptor()
  116. Index: service.cpp
  117. ===================================================================
  118. --- service.cpp (revision 1153)
  119. +++ service.cpp (working copy)
  120. @@ -49,7 +49,11 @@
  121. #include "views_pool.h"
  122. #include "session_pool.h"
  123. +#ifndef CPPCMS_WIN32
  124. +#include "proc_acceptor.h"
  125. +#endif
  126. +
  127. #ifdef CPPCMS_POSIX
  128. #include <sys/wait.h>
  129. #endif
  130. @@ -304,6 +308,17 @@
  131. #endif
  132. }
  133. +void service::reset_service()
  134. +{
  135. + #ifndef CPPCMS_WIN32
  136. + std::auto_ptr<boost::asio::io_service> new_service(new boost::asio::io_service());
  137. + for(unsigned i=0;i<impl_->acceptors_.size();i++)
  138. + impl_->acceptors_[i]=impl_->acceptors_[i]->clone(*new_service);
  139. + impl_->io_service_ = new_service;
  140. +
  141. + #endif
  142. +}
  143. +
  144. void service::after_fork(function<void()> const &cb)
  145. {
  146. impl_->on_fork_.push_back(cb);
  147. @@ -313,27 +328,46 @@
  148. {
  149. generator();
  150. session_pool().init();
  151. +
  152. + #ifndef CPPCMS_WIN32
  153. + //if(procs_no() > 1) {
  154. + impl_->process_shared_acceptor_.reset(new impl::process_shared_acceptor(*this));
  155. + //}
  156. + #endif
  157. +
  158. start_acceptor();
  159. if(settings().get("file_server.enable",false))
  160. applications_pool().mount(applications_factory<cppcms::impl::file_server>(),"");
  161. + std::cout << "FORKING" << std::endl;
  162. +
  163. if(prefork()) {
  164. return;
  165. }
  166. thread_pool(); // make sure we start it
  167. +
  168. for(unsigned i=0;i<impl_->on_fork_.size();i++)
  169. impl_->on_fork_[i]();
  170. impl_->on_fork_.clear();
  171. +
  172. + #ifndef CPPCMS_WIN32
  173. + //if(procs_no() > 1) {
  174. + reset_service();
  175. + //}
  176. + #endif
  177. for(unsigned i=0;i<impl_->acceptors_.size();i++)
  178. impl_->acceptors_[i]->async_accept();
  179. setup_exit_handling();
  180. +
  181. + std::cout << "LOOPING" << std::endl;
  182. impl_->get_io_service().run();
  183. + std::cout << "Exitting " << std::endl;
  184. }
  185. int service::procs_no()
  186. @@ -668,6 +702,12 @@
  187. service::~service()
  188. {
  189. acceptors_.clear();
  190. + #ifndef CPPCMS_WIN32
  191. + if(process_shared_acceptor_.get()) {
  192. + process_shared_acceptor_->stop();
  193. + process_shared_acceptor_.reset();
  194. + }
  195. + #endif
  196. thread_pool_.reset();
  197. sig_.reset();
  198. breaker_.reset();
  199. Index: cgi_api.h
  200. ===================================================================
  201. --- cgi_api.h (revision 1153)
  202. +++ cgi_api.h (working copy)
  203. @@ -24,6 +24,7 @@
  204. #include "intrusive_ptr.h"
  205. #include <vector>
  206. #include <map>
  207. +#include <memory>
  208. #include "function.h"
  209. #include "config.h"
  210. #ifdef CPPCMS_USE_EXTERNAL_BOOST
  211. @@ -58,6 +59,7 @@
  212. public:
  213. virtual void async_accept() = 0;
  214. virtual void stop() = 0;
  215. + virtual std::auto_ptr<acceptor> clone(boost::asio::io_service &) = 0;
  216. virtual ~acceptor(){}
  217. };
  218. Index: cgi_acceptor.h
  219. ===================================================================
  220. --- cgi_acceptor.h (revision 1153)
  221. +++ cgi_acceptor.h (working copy)
  222. @@ -32,7 +32,13 @@
  223. # include <cppcms_boost/bind.hpp>
  224. namespace boost = cppcms_boost;
  225. #endif
  226. +#ifndef CPPCMS_WIN32
  227. +#include "proc_acceptor.h"
  228. +#include <unistd.h>
  229. +#endif
  230. +
  231. +
  232. namespace cppcms {
  233. namespace impl {
  234. namespace cgi {
  235. @@ -40,12 +46,33 @@
  236. template<typename Proto,class ServerAPI>
  237. class socket_acceptor : public acceptor {
  238. public:
  239. + socket_acceptor(cppcms::service &srv,boost::asio::io_service &iosrv) :
  240. + srv_(srv),
  241. + acceptor_(iosrv),
  242. + stopped_(false)
  243. + {
  244. + }
  245. socket_acceptor(cppcms::service &srv) :
  246. srv_(srv),
  247. acceptor_(srv_.impl().get_io_service()),
  248. stopped_(false)
  249. {
  250. }
  251. + virtual std::auto_ptr<acceptor> clone(boost::asio::io_service &iosrv)
  252. + {
  253. + #ifdef CPPCMS_WIN32
  254. + throw cppcms_error("Internal error - cloning should not be done under Windows platform");
  255. + #else
  256. + std::auto_ptr<socket_acceptor<Proto,ServerAPI> > tmp(new socket_acceptor<Proto,ServerAPI>(srv_,iosrv));
  257. + int newfd = ::dup(acceptor_.native());
  258. + if(newfd < 0)
  259. + throw cppcms_error(errno,"Dup failed");
  260. + tmp->acceptor_.assign(acceptor_.local_endpoint().protocol(),newfd);
  261. + std::auto_ptr<acceptor> tmp2;
  262. + tmp2 = tmp;
  263. + return tmp2;
  264. + #endif
  265. + }
  266. virtual void async_accept()
  267. {
  268. if(stopped_)
  269. @@ -53,11 +80,24 @@
  270. ServerAPI *api=new ServerAPI(srv_);
  271. api_=api;
  272. asio_socket_ = &api->socket_;
  273. - acceptor_.async_accept(
  274. - *asio_socket_,
  275. - boost::bind( &socket_acceptor::on_accept,
  276. - this,
  277. - boost::asio::placeholders::error));
  278. +#ifndef CPPCMS_WIN32
  279. + if(srv_.impl().process_shared_acceptor_.get()) {
  280. + srv_.impl().process_shared_acceptor_->async_accept(
  281. + acceptor_,
  282. + *asio_socket_,
  283. + boost::bind( &socket_acceptor::on_accept,
  284. + this,
  285. + boost::asio::placeholders::error));
  286. + }
  287. + else
  288. +#endif
  289. + {
  290. + acceptor_.async_accept(
  291. + *asio_socket_,
  292. + boost::bind( &socket_acceptor::on_accept,
  293. + this,
  294. + boost::asio::placeholders::error));
  295. + }
  296. }
  297. virtual void stop()
  298. {
  299. Index: service.h
  300. ===================================================================
  301. --- service.h (revision 1153)
  302. +++ service.h (working copy)
  303. @@ -80,6 +80,7 @@
  304. void start_acceptor();
  305. void setup_exit_handling();
  306. bool prefork();
  307. + void reset_service();
  308. util::hold_ptr<impl::service> impl_;
  309. };
  310. Index: service_impl.h
  311. ===================================================================
  312. --- service_impl.h (revision 1153)
  313. +++ service_impl.h (working copy)
  314. @@ -31,6 +31,7 @@
  315. class session_pool;
  316. namespace impl {
  317. + class process_shared_acceptor;
  318. namespace cgi {
  319. class acceptor;
  320. }
  321. @@ -44,6 +45,9 @@
  322. return *io_service_;
  323. }
  324. + #ifndef CPPCMS_WIN32
  325. + std::auto_ptr<process_shared_acceptor> process_shared_acceptor_;
  326. + #endif
  327. private:
  328. friend class cppcms::service;
  329. Index: CMakeLists.txt
  330. ===================================================================
  331. --- CMakeLists.txt (revision 1153)
  332. +++ CMakeLists.txt (working copy)
  333. @@ -520,7 +520,7 @@
  334. if(WIN32 AND NOT CYGWIN)
  335. set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_win32_file_storage.cpp)
  336. else(WIN32 AND NOT CYGWIN)
  337. - set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_posix_file_storage.cpp)
  338. + set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_posix_file_storage.cpp proc_acceptor.cpp)
  339. endif(WIN32 AND NOT CYGWIN)
  340. if(NOT DISABLE_SHARED)
  341. Index: proc_acceptor.h
  342. ===================================================================
  343. --- proc_acceptor.h (revision 1153)
  344. +++ proc_acceptor.h (working copy)
  345. @@ -29,7 +29,7 @@
  346. ~process_shared_acceptor();
  347. template<typename Socket1,typename Socket2>
  348. - void async_accept(Socket1 acc,Socket2 sock,on_accept_function const &on_accepted)
  349. + void async_accept(Socket1 &acc,Socket2 &sock,on_accept_function const &on_accepted)
  350. {
  351. int fd = acc.native();
  352. {
  353. @@ -38,16 +38,28 @@
  354. if(fd + 1 > max_1_ )
  355. max_1_ = fd+1;
  356. callbacks_[fd]=on_accepted;
  357. - assigners_[fd]=boost::bind(&Socket2::assign,&sock,_1);
  358. + assigner<Socket2> as = { &sock, acc.local_endpoint().protocol() };
  359. + assigners_[fd]=as;
  360. }
  361. wake();
  362. }
  363. - void stop()
  364. + void start();
  365. + void stop();
  366. + private:
  367. +
  368. + template<typename Socket>
  369. + struct assigner
  370. {
  371. - stop_ = true;
  372. - wake();
  373. - }
  374. - private:
  375. + typedef typename Socket::protocol_type protocol_type;
  376. + Socket *sock;
  377. + protocol_type proto;
  378. + void operator()(int fd) const
  379. + {
  380. + sock->assign(proto,fd);
  381. + }
  382. + };
  383. +
  384. +
  385. void on_fork();
  386. void wake();
  387. bool run_one();
  388. @@ -64,6 +76,7 @@
  389. std::vector<on_accept_function> callbacks_;
  390. std::vector<assign_function> assigners_;
  391. boost::asio::io_service *service_;
  392. + std::auto_ptr<boost::thread> worker_;
  393. }
  394. ;
  395. }