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.
 
 
 
 
 
 

415 lines
13 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_APPLICATIONS_POOL_H
  9. #define CPPCMS_APPLICATIONS_POOL_H
  10. #include <cppcms/defs.h>
  11. #include <booster/noncopyable.h>
  12. #include <booster/hold_ptr.h>
  13. #include <booster/intrusive_ptr.h>
  14. #include <booster/shared_ptr.h>
  15. #include <booster/weak_ptr.h>
  16. #include <booster/enable_shared_from_this.h>
  17. #include <booster/auto_ptr_inc.h>
  18. #include <string>
  19. namespace cppcms {
  20. class application;
  21. }
  22. namespace booster {
  23. void CPPCMS_API intrusive_ptr_add_ref(cppcms::application *p);
  24. void CPPCMS_API intrusive_ptr_release(cppcms::application *p);
  25. namespace aio {
  26. class io_service;
  27. }
  28. }
  29. namespace cppcms {
  30. class service;
  31. class mount_point;
  32. class application_specific_pool;
  33. class applications_pool;
  34. namespace http {
  35. class context;
  36. }
  37. ///
  38. /// \brief Flags for application pool management
  39. ///
  40. /// \ver{v1_2}
  41. namespace app {
  42. static const int synchronous = 0x0000; ///< Synchronous application
  43. static const int asynchronous = 0x0001; ///< Asynchronous application that operates in asynchronous mode
  44. static const int op_mode_mask = 0x000F; ///< mask to select sync vs async flags
  45. static const int thread_specific= 0x0010; ///< Make synchronous application thread specific
  46. static const int prepopulated = 0x0020; ///< Make sure all applications are created from the beginning (ignored in thread_specific is set)
  47. static const int content_filter = 0x0040; ///< Make this asynchronous application to handle content
  48. /// \cond INTERNAL
  49. static const int legacy = 0x8000; ///< Use legacy handling of application life time when the application is created in the event loop and than dispatched as a job to a thread pool
  50. /// \endcond
  51. }
  52. ///
  53. /// \brief an interface for creating user applications
  54. ///
  55. /// \ver{v1_2}
  56. class CPPCMS_API application_specific_pool :
  57. public booster::noncopyable,
  58. public booster::enable_shared_from_this<application_specific_pool>
  59. {
  60. public:
  61. application_specific_pool();
  62. virtual ~application_specific_pool();
  63. ///
  64. /// Returns asynchronous application that runs at given booster::aio::io_service constext, it the application
  65. /// does not exist yet, it is created
  66. ///
  67. /// Notes:
  68. ///
  69. /// - if the application is created upon function call it would be created in the calling thread regardless if it is event loop thread or not
  70. /// - If the pool isn't mounted as asynchronous pool then cppcms_error is thrown
  71. /// - if the io_srv isn't main cppcms io_service cppcms_error is thrown
  72. ///
  73. booster::intrusive_ptr<application> asynchronous_application_by_io_service(booster::aio::io_service &io_srv,cppcms::service &srv);
  74. ///
  75. /// Returns asynchronous application that runs at given booster::aio::io_service constext, it the application
  76. /// does not exist yet NULL pointer is returned
  77. ///
  78. /// Notes:
  79. ///
  80. /// - If the pool isn't mounted as asynchronous pool then cppcms_error is thrown
  81. /// - if the io_srv isn't main cppcms io_service cppcms_error is thrown
  82. ///
  83. booster::intrusive_ptr<application> asynchronous_application_by_io_service(booster::aio::io_service &io_srv);
  84. protected:
  85. ///
  86. /// Returns newly created instance of an application, its ownership
  87. /// is transferred
  88. ///
  89. virtual application *new_application(service &srv) = 0;
  90. private:
  91. int flags();
  92. void flags(int f);
  93. void prepopulate(cppcms::service &srv);
  94. void application_requested(cppcms::service &srv);
  95. friend class applications_pool;
  96. friend class application;
  97. friend class http::context;
  98. friend void booster::intrusive_ptr_release(cppcms::application *app);
  99. application *get_new(service &srv);
  100. void size(size_t n);
  101. booster::intrusive_ptr<application> get(service &);
  102. void put(application *app);
  103. struct _data;
  104. class _policy;
  105. class _tls_policy;
  106. class _pool_policy;
  107. class _async_policy;
  108. class _async_legacy_policy;
  109. class _legacy_pool_policy;
  110. booster::hold_ptr<_data> d;
  111. };
  112. ///
  113. /// \brief Application pool is the central class that holds user created applications
  114. ///
  115. /// Form the user perspective this class provides an API for mounting user application to the CppCMS service.
  116. ///
  117. /// There are two kind of \a mount member functions, that allow:
  118. ///
  119. /// - Mounting a \a factory of user applications -- for execution of synchronous requests by multiple
  120. /// instances of application.
  121. /// - Mounting single application -- for processing asynchronous requests by single instance of an application
  122. ///
  123. /// The life cycle of synchronous application is defined by application pool itself, and the life cycle
  124. /// of asynchronous depends on its own reference count.
  125. ///
  126. /// This class is thread safe and can be accessed from multiple threads simultaneously.
  127. ///
  128. class CPPCMS_API applications_pool {
  129. public:
  130. ///
  131. /// \brief a base class for user application factories - to be deprecated, use
  132. /// application_specific_pool instead
  133. ///
  134. /// \deprecated Use application_specific_pool
  135. ///
  136. struct factory : public booster::noncopyable {
  137. ///
  138. /// Returns newly created instance of an application.
  139. ///
  140. virtual std::auto_ptr<application> operator()(service &) const = 0;
  141. virtual ~factory(){}
  142. };
  143. ///
  144. /// Mount an application factory \a aps for processing of any incoming requests. Application
  145. /// would receive PATH_INFO CGI variable for URL matching.
  146. ///
  147. /// This member function is thread safe.
  148. ///
  149. /// \deprecated Use mount(booster::shared_ptr<application_specific_pool> gen,int application_options) instead
  150. ///
  151. void mount(std::auto_ptr<factory> aps);
  152. ///
  153. /// Mount an application factory \a app by mount_point \a point application matching and
  154. /// URL selection rules
  155. ///
  156. /// This member function is thread safe.
  157. ///
  158. /// \deprecated Use mount(booster::shared_ptr<application_specific_pool> gen,mount_point const &point,int application_options) instead
  159. ///
  160. void mount(std::auto_ptr<factory> aps,mount_point const &point);
  161. ///
  162. /// Mount an asynchronous application \a app for processing of any incoming requests. Application
  163. /// would receive PATH_INFO CGI variable for URL matching.
  164. ///
  165. /// This member function is thread safe.
  166. ///
  167. /// \deprecated Use mount(booster::shared_ptr<application_specific_pool> gen,int application_options) with application_options=app::asynchronous instead
  168. ///
  169. void mount(booster::intrusive_ptr<application> app);
  170. ///
  171. /// Mount an asynchronous application \a app by mount_point \a point application matching and
  172. /// URL selection rules
  173. ///
  174. /// This member function is thread safe.
  175. ///
  176. /// \deprecated Use mount(booster::shared_ptr<application_specific_pool> gen,mount_point const &point,int application_options) with application_options=app::asynchronous instead
  177. ///
  178. void mount(booster::intrusive_ptr<application> app,mount_point const &point);
  179. ///
  180. /// Mount a application_specific_pool for an application that processes all requests, path provided to application's main is PATH_INFO
  181. ///
  182. /// \a application_options allow to specify mode of operation - synchronous, asynchronous, see namespace
  183. /// cppcms::app
  184. ///
  185. /// Note: applications_pool owns gen now and is responsible for destroying it
  186. ///
  187. /// This member function is thread safe.
  188. ///
  189. /// \ver{v1_2}
  190. void mount(booster::shared_ptr<application_specific_pool> gen,int application_options = 0);
  191. ///
  192. /// Mount a application_specific_pool to a specific mount point
  193. ///
  194. /// \a application_options allow to specify mode of operation - synchronous, asynchronous, see namespace
  195. /// cppcms::app
  196. ///
  197. /// Note: applications_pool owns gen now and is responsible for destroying it
  198. ///
  199. /// This member function is thread safe.
  200. ///
  201. /// \ver{v1_2}
  202. void mount(booster::shared_ptr<application_specific_pool> gen,mount_point const &point,int application_options = 0);
  203. ///
  204. /// Unmount an application_specific_pool from the general pool.
  205. ///
  206. /// Notes:
  207. ///
  208. /// - Exiting request would continue to be executed
  209. /// - There is no guarantee when and in which thread application objects would be destroyed upon use of unmount
  210. /// - applications in the pool using thread_specific policy would be destroyed only on thread exit (i.e. when threads of thread pool are destroyed)
  211. ///
  212. /// This member function is thread safe.
  213. ///
  214. /// \ver{v1_2}
  215. void unmount(booster::weak_ptr<application_specific_pool> gen);
  216. /// \cond INTERNAL
  217. /// get is not in use any more
  218. booster::intrusive_ptr<application>
  219. get(char const *h,char const *s,char const *path_info,std::string &match);
  220. booster::shared_ptr<application_specific_pool>
  221. get_application_specific_pool(char const *h,char const *s,char const *path_info,std::string &match);
  222. // put is not in use any more
  223. void put(application *app);
  224. applications_pool(service &srv,int unused);
  225. ~applications_pool();
  226. /// \endcond
  227. private:
  228. struct _data;
  229. service *srv_;
  230. booster::hold_ptr<_data> d;
  231. };
  232. /// \cond INTERNAL
  233. namespace details {
  234. template<typename T>
  235. struct simple_factory0 : public applications_pool::factory
  236. {
  237. std::auto_ptr<application> operator()(service &s) const
  238. {
  239. std::auto_ptr<application> app(new T(s));
  240. return app;
  241. }
  242. };
  243. template<typename T,typename P1>
  244. struct simple_factory1 : public applications_pool::factory
  245. {
  246. simple_factory1(P1 p1) : p1_(p1) {}
  247. P1 p1_;
  248. std::auto_ptr<application> operator()(service &s) const
  249. {
  250. std::auto_ptr<application> app(new T(s,p1_));
  251. return app;
  252. }
  253. };
  254. template<typename T,typename P1,typename P2>
  255. struct simple_factory2 : public applications_pool::factory
  256. {
  257. simple_factory2(P1 p1,P2 p2) : p1_(p1),p2_(p2) {}
  258. P1 p1_;
  259. P2 p2_;
  260. std::auto_ptr<application> operator()(service &s) const
  261. {
  262. std::auto_ptr<application> app(new T(s,p1_,p2_));
  263. return app;
  264. }
  265. };
  266. } // details
  267. /// \endcond
  268. ///
  269. /// Create application factory for application of type T, such as T has a constructor
  270. /// T::T(cppcms::service &s);
  271. ///
  272. /// \deprecated Use create_pool
  273. ///
  274. template<typename T>
  275. std::auto_ptr<applications_pool::factory> applications_factory()
  276. {
  277. std::auto_ptr<applications_pool::factory> f(new details::simple_factory0<T>);
  278. return f;
  279. }
  280. ///
  281. /// Create application factory for application of type T, such as T has a constructor
  282. /// T::T(cppcms::service &s,P1);
  283. ///
  284. /// \deprecated Use create_pool
  285. ///
  286. template<typename T,typename P1>
  287. std::auto_ptr<applications_pool::factory> applications_factory(P1 p1)
  288. {
  289. std::auto_ptr<applications_pool::factory> f(new details::simple_factory1<T,P1>(p1));
  290. return f;
  291. }
  292. ///
  293. /// Create application factory for application of type T, such as T has a constructor
  294. /// T::T(cppcms::service &s,P1,P2);
  295. ///
  296. /// \deprecated Use create_pool
  297. ///
  298. template<typename T,typename P1,typename P2>
  299. std::auto_ptr<applications_pool::factory> applications_factory(P1 p1,P2 p2)
  300. {
  301. std::auto_ptr<applications_pool::factory> f(new details::simple_factory2<T,P1,P2>(p1,p2));
  302. return f;
  303. }
  304. /// \cond INTERNAL
  305. namespace details {
  306. template<typename T>
  307. struct simple_application_specific_pool0 : public application_specific_pool
  308. {
  309. T *new_application(service &s)
  310. {
  311. return new T(s);
  312. }
  313. };
  314. template<typename T,typename P1>
  315. struct simple_application_specific_pool1 : public application_specific_pool
  316. {
  317. simple_application_specific_pool1(P1 p1) : p1_(p1) {}
  318. P1 p1_;
  319. T *new_application(service &s)
  320. {
  321. return new T(s,p1_);
  322. }
  323. };
  324. template<typename T,typename P1,typename P2>
  325. struct simple_application_specific_pool2 : public application_specific_pool
  326. {
  327. simple_application_specific_pool2(P1 p1,P2 p2) : p1_(p1),p2_(p2) {}
  328. P1 p1_;
  329. P2 p2_;
  330. T *new_application(service &s)
  331. {
  332. return new T(s,p1_,p2_);
  333. }
  334. };
  335. } // details
  336. /// \endcond
  337. ///
  338. /// Create application application_specific_pool for application of type T, such as T has a constructor
  339. /// T::T(cppcms::service &s);
  340. ///
  341. template<typename T>
  342. booster::shared_ptr<application_specific_pool> create_pool()
  343. {
  344. booster::shared_ptr<application_specific_pool> f(new details::simple_application_specific_pool0<T>);
  345. return f;
  346. }
  347. ///
  348. /// Create application application_specific_pool for application of type T, such as T has a constructor
  349. /// T::T(cppcms::service &s,P1);
  350. ///
  351. template<typename T,typename P1>
  352. booster::shared_ptr<application_specific_pool> create_pool(P1 p1)
  353. {
  354. booster::shared_ptr<application_specific_pool> f(new details::simple_application_specific_pool1<T,P1>(p1));
  355. return f;
  356. }
  357. ///
  358. /// Create application application_specific_pool for application of type T, such as T has a constructor
  359. /// T::T(cppcms::service &s,P1,P2);
  360. ///
  361. template<typename T,typename P1,typename P2>
  362. booster::shared_ptr<application_specific_pool> create_pool(P1 p1,P2 p2)
  363. {
  364. booster::shared_ptr<application_specific_pool> f(new details::simple_application_specific_pool2<T,P1,P2>(p1,p2));
  365. return f;
  366. }
  367. } // cppcms
  368. #endif