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.
 
 
 
 
 
 

263 lines
5.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU Lesser General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public License
  16. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #define CPPCMS_SOURCE
  20. #include "application.h"
  21. #include "http_context.h"
  22. #include "service.h"
  23. #include "cppcms_error.h"
  24. #include "url_dispatcher.h"
  25. #include "intrusive_ptr.h"
  26. #include "applications_pool.h"
  27. #include "http_response.h"
  28. #include "views_pool.h"
  29. #include <set>
  30. #include <vector>
  31. #include "config.h"
  32. #ifdef CPPCMS_USE_EXTERNAL_BOOST
  33. # include <boost/bind.hpp>
  34. #else // Internal Boost
  35. # include <cppcms_boost/bind.hpp>
  36. namespace boost = cppcms_boost;
  37. #endif
  38. namespace cppcms {
  39. struct application::data {
  40. data(cppcms::service *s):
  41. service(s),
  42. conn(0),
  43. pool_id(-1)
  44. {
  45. }
  46. cppcms::service *service;
  47. intrusive_ptr<http::context> conn;
  48. int pool_id;
  49. url_dispatcher url;
  50. std::vector<application *> managed_children;
  51. };
  52. application::application(cppcms::service &srv) :
  53. d(new data(&srv)),
  54. refs_(0)
  55. {
  56. parent_=root_=this;
  57. }
  58. application::~application()
  59. {
  60. for(unsigned i=0;i<d->managed_children.size();i++) {
  61. delete d->managed_children[i];
  62. d->managed_children[i]=0;
  63. }
  64. }
  65. cppcms::service &application::service()
  66. {
  67. return *d->service;
  68. }
  69. json::value const &application::settings()
  70. {
  71. return service().settings();
  72. }
  73. http::request &application::request()
  74. {
  75. return context().request();
  76. }
  77. http::response &application::response()
  78. {
  79. return context().response();
  80. }
  81. url_dispatcher &application::dispatcher()
  82. {
  83. return d->url;
  84. }
  85. intrusive_ptr<http::context> application::get_context()
  86. {
  87. return root()->d->conn;
  88. }
  89. http::context &application::context()
  90. {
  91. if(!root()->d->conn)
  92. throw cppcms_error("Access to unassigned context");
  93. return *root()->d->conn;
  94. }
  95. intrusive_ptr<http::context> application::release_context()
  96. {
  97. intrusive_ptr<http::context> ptr=root()->d->conn;
  98. assign_context(0);
  99. return ptr;
  100. }
  101. bool application::is_asynchronous()
  102. {
  103. return pool_id() < 0;
  104. }
  105. void application::assign_context(intrusive_ptr<http::context> conn)
  106. {
  107. root()->d->conn=conn;
  108. }
  109. void application::pool_id(int id)
  110. {
  111. d->pool_id=id;
  112. }
  113. int application::pool_id()
  114. {
  115. return d->pool_id;
  116. }
  117. application *application::parent()
  118. {
  119. return parent_;
  120. }
  121. application *application::root()
  122. {
  123. return root_;
  124. }
  125. void application::parent(application *app)
  126. {
  127. parent_=app;
  128. root_=app->root();
  129. }
  130. void application::add(application &app)
  131. {
  132. if(app.parent()!=this)
  133. app.parent(this);
  134. }
  135. void application::add(application &app,std::string regex,int part)
  136. {
  137. add(app);
  138. url_dispatcher().mount(regex,app,part);
  139. }
  140. void application::attach(application *app)
  141. {
  142. d->managed_children.push_back(app);
  143. add(*app);
  144. }
  145. void application::main(std::string url)
  146. {
  147. if(!dispatcher().dispatch(url)) {
  148. response().make_error_response(http::response::not_found);
  149. }
  150. }
  151. void application::attach(application *app,std::string regex,int part)
  152. {
  153. d->managed_children.push_back(app);
  154. add(*app,regex,part);
  155. }
  156. void application::render(std::string template_name,base_content &content)
  157. {
  158. service().views_pool().render(context().skin(),template_name,response().out(),content);
  159. }
  160. void application::render(std::string skin,std::string template_name,base_content &content)
  161. {
  162. service().views_pool().render(skin,template_name,response().out(),content);
  163. }
  164. void application::render(std::string template_name,std::ostream &out,base_content &content)
  165. {
  166. service().views_pool().render(context().skin(),template_name,out,content);
  167. }
  168. void application::render(std::string skin,std::string template_name,std::ostream &out,base_content &content)
  169. {
  170. service().views_pool().render(skin,template_name,out,content);
  171. }
  172. cache_interface &application::cache()
  173. {
  174. return context().cache();
  175. }
  176. session_interface &application::session()
  177. {
  178. return context().session();
  179. }
  180. void application::recycle()
  181. {
  182. if(root()->d->conn) {
  183. response().finalize();
  184. context().async_complete_response();
  185. }
  186. assign_context(0);
  187. }
  188. void intrusive_ptr_add_ref(application *app)
  189. {
  190. ++(app->root()->refs_);
  191. }
  192. // REMEMBER THIS IS CALLED FROM DESTRUCTOR!!!
  193. void intrusive_ptr_release(application *app)
  194. {
  195. // it is called in destructors... So be very careful
  196. try {
  197. app = app->root();
  198. long refs=--(app->refs_);
  199. if(refs > 0)
  200. return;
  201. cppcms::service &service=app->service();
  202. try {
  203. app->recycle();
  204. }
  205. catch(...) {
  206. if(app->pool_id() < 0) {
  207. service.applications_pool().put(app);
  208. }
  209. else
  210. delete app;
  211. throw;
  212. }
  213. service.applications_pool().put(app);
  214. // return the application to pool... or delete it if "pooled"
  215. }
  216. catch(...)
  217. {
  218. // FIXME LOG IT?
  219. }
  220. }
  221. } // cppcms