PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/boost/cgi/connections/shareable_tcp_socket.hpp

http://github.com/darrengarvey/cgi
C++ Header | 221 lines | 153 code | 33 blank | 35 comment | 5 complexity | 813986dc236084a18e6c2dec2f5ad44f MD5 | raw file
  1. // -- connections/shareable_tcp_socket.hpp --
  2. //
  3. // Copyright (c) Darren Garvey 2007.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ////////////////////////////////////////////////////////////////
  9. #ifndef CGI_CONNECTIONS_SHAREABLE_TCP_SOCKET_HPP_INCLUDED__
  10. #define CGI_CONNECTIONS_SHAREABLE_TCP_SOCKET_HPP_INCLUDED__
  11. #include <map>
  12. #include <set>
  13. ///////////////////////////////////////////////////////////
  14. #include <boost/asio.hpp>
  15. #include <boost/thread.hpp>
  16. #include <boost/cstdint.hpp>
  17. #include <boost/foreach.hpp>
  18. #include <boost/shared_ptr.hpp>
  19. ///////////////////////////////////////////////////////////
  20. #include "boost/cgi/error.hpp"
  21. #include "boost/cgi/common/tags.hpp"
  22. #include "boost/cgi/basic_connection.hpp"
  23. #include "boost/cgi/import/io_service.hpp"
  24. #include "boost/cgi/detail/push_options.hpp"
  25. #include "boost/cgi/common/connection_base.hpp"
  26. #include "boost/cgi/fcgi/traits.hpp"
  27. #include "boost/cgi/common/protocol_traits.hpp"
  28. BOOST_CGI_NAMESPACE_BEGIN
  29. namespace common {
  30. /*** 05.02.2008 :
  31. * I'm planning on making this class a more FastCGI-specific one since a
  32. * rereading of the FastCGI spec (ie. 'Managing request IDs') made me
  33. * realise that IDs are connection specific, not just application specific.
  34. *
  35. * IOW when checking to see if a particular request id exists, rather than
  36. * having to check a table in the protocol_service (which may imply explicit
  37. * mutex use), we can just check a local array of values. Good good.
  38. ***/
  39. template<>
  40. class basic_connection<tags::shareable_tcp_socket>
  41. : public connection_base
  42. {
  43. public:
  44. typedef boost::shared_ptr<
  45. basic_connection<tags::shareable_tcp_socket> > pointer;
  46. typedef boost::mutex mutex_type;
  47. struct condition_type : public boost::condition_variable
  48. { typedef boost::shared_ptr<boost::condition_variable> pointer; };
  49. typedef boost::mutex::scoped_lock scoped_lock_type;
  50. typedef boost::asio::ip::tcp::socket next_layer_type;
  51. typedef common::protocol_traits<tags::fcgi> traits;
  52. /** FastCGI specific stuff **/
  53. typedef traits::request_type request_type;
  54. typedef boost::shared_ptr<request_type> request_ptr;
  55. typedef std::map<boost::uint16_t, request_type*> request_map_type;
  56. typedef std::vector<request_type*> request_vector_type;
  57. /** End FastCGI stuff **/
  58. // A wrapper to provide condition_type::pointer
  59. basic_connection(io_service& ios)
  60. : sock_(ios)
  61. , mutex_()
  62. , condition_()
  63. {
  64. }
  65. ~basic_connection()
  66. {
  67. //BOOST_FOREACH(boost::uint16_t id, deletable_request_ids_)
  68. //{
  69. // delete requests_.at(id-1);
  70. // requests_.at(id-1) = 0;
  71. //}
  72. }
  73. bool is_open() const
  74. {
  75. return sock_.is_open();
  76. }
  77. void close()
  78. {
  79. sock_.close();
  80. }
  81. void lock()
  82. {
  83. scoped_lock_type lock(mutex_);
  84. locked_ = true;
  85. }
  86. void unlock()
  87. {
  88. scoped_lock_type lock(mutex_);
  89. locked_ = false;
  90. condition_.notify_one();
  91. }
  92. void wait()
  93. {
  94. scoped_lock_type lock(mutex_);
  95. if (locked_ == false)
  96. return;
  97. condition_.wait(lock);
  98. }
  99. static pointer create(io_service& ios)
  100. {
  101. return //static_cast<pointer>(
  102. pointer(new basic_connection<tags::shareable_tcp_socket>(ios));
  103. }
  104. template<typename MutableBufferSequence>
  105. std::size_t read_some(const MutableBufferSequence& buf)
  106. {
  107. return sock_.read_some(buf);
  108. }
  109. template<typename MutableBufferSequence>
  110. std::size_t read_some(const MutableBufferSequence& buf
  111. , boost::system::error_code& ec)
  112. {
  113. return sock_.read_some(buf, ec);
  114. }
  115. template<typename MutableBufferSequence, typename Handler>
  116. void async_read_some(const MutableBufferSequence& buf, Handler handler)
  117. {
  118. sock_.async_read_some(buf, handler);
  119. }
  120. template<typename ConstBufferSequence>
  121. std::size_t write_some(ConstBufferSequence& buf)
  122. {
  123. return sock_.write_some(buf);
  124. }
  125. template<typename ConstBufferSequence>
  126. std::size_t write_some(ConstBufferSequence& buf
  127. , boost::system::error_code& ec)
  128. {
  129. return sock_.write_some(buf, ec);
  130. }
  131. template<typename ConstBufferSequence, typename Handler>
  132. void async_write_some(ConstBufferSequence& buf, Handler handler)
  133. {
  134. sock_.async_write_some(buf, handler);
  135. }
  136. next_layer_type&
  137. next_layer()
  138. {
  139. return sock_;
  140. }
  141. mutex_type& mutex() { return mutex_; }
  142. condition_type& condition() { return condition_; }
  143. boost::system::error_code
  144. get_slot(boost::uint16_t id, boost::system::error_code& ec)
  145. {
  146. if (requests_.at(id-1)) // duplicate request!
  147. {
  148. return error::duplicate_request;
  149. }
  150. if (requests_.size() < boost::uint16_t(id-1))
  151. requests_.resize(id);
  152. return ec;
  153. }
  154. boost::system::error_code
  155. add_request(boost::uint16_t id, request_type* req, bool on_heap
  156. , boost::system::error_code& ec)
  157. {
  158. requests_.at(id-1) = req;
  159. if (on_heap)
  160. deletable_request_ids_.insert(id);
  161. return ec;
  162. }
  163. //template<typename RequestImpl>
  164. //boost::system::error_code
  165. // multiplex(RequestImpl& impl, boost::system::error_code& ec)
  166. //{
  167. //
  168. // return ec;
  169. //}
  170. private:
  171. bool locked_;
  172. next_layer_type sock_;
  173. mutex_type mutex_;
  174. condition_type condition_;
  175. public:
  176. /** FastCGI specific stuff **/
  177. request_map_type request_map_;
  178. request_vector_type requests_;
  179. std::set<int> deletable_request_ids_;
  180. };
  181. } // namespace common
  182. namespace connections {
  183. typedef common::basic_connection<
  184. common::tags::shareable_tcp_socket> shareable_tcp;
  185. } // namespace connections
  186. BOOST_CGI_NAMESPACE_END
  187. #include "boost/cgi/detail/pop_options.hpp"
  188. #endif // CGI_CONNECTIONS_SHAREABLE_TCP_SOCKET_HPP_INCLUDED__