1 // Copyright (c) Benjamin Kietzman (github.com/bkietz) 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef DBUS_CONNECTION_SERVICE_HPP 7 #define DBUS_CONNECTION_SERVICE_HPP 8 9 #include <boost/asio.hpp> 10 #include <boost/asio/io_service.hpp> 11 12 #include <dbus/detail/async_send_op.hpp> 13 #include <dbus/element.hpp> 14 #include <dbus/error.hpp> 15 #include <dbus/message.hpp> 16 17 #include <dbus/impl/connection.ipp> 18 19 namespace dbus { 20 namespace bus { 21 static const int session = DBUS_BUS_SESSION; 22 static const int system = DBUS_BUS_SYSTEM; 23 static const int starter = DBUS_BUS_STARTER; 24 } // namespace bus 25 26 class filter; 27 class match; 28 class connection; 29 30 class connection_service 31 : public boost::asio::detail::service_base<connection_service> { 32 public: 33 typedef impl::connection implementation_type; 34 connection_service(boost::asio::io_service & io)35 inline explicit connection_service(boost::asio::io_service& io) 36 : boost::asio::detail::service_base<connection_service>(io) {} 37 construct(implementation_type & impl)38 inline void construct(implementation_type& impl) {} 39 destroy(implementation_type & impl)40 inline void destroy(implementation_type& impl) {} 41 shutdown_service()42 inline void shutdown_service() { 43 // TODO is there anything that needs shutting down? 44 } 45 open(implementation_type & impl,const string & address)46 inline void open(implementation_type& impl, const string& address) { 47 boost::asio::io_service& io = this->get_io_service(); 48 49 impl.open(io, address); 50 } 51 open(implementation_type & impl,const int bus=bus::system)52 inline void open(implementation_type& impl, const int bus = bus::system) { 53 boost::asio::io_service& io = this->get_io_service(); 54 55 impl.open(io, bus); 56 } 57 send(implementation_type & impl,message & m)58 inline message send(implementation_type& impl, message& m) { 59 return impl.send_with_reply_and_block(m); 60 } 61 62 template <typename Duration> send(implementation_type & impl,message & m,const Duration & timeout)63 inline message send(implementation_type& impl, message& m, 64 const Duration& timeout) { 65 if (timeout == Duration::zero()) { 66 // TODO this can return false if it failed 67 impl.send(m); 68 // TODO(ed) rework API to seperate blocking and non blocking sends 69 return message(nullptr); 70 } else { 71 return impl.send_with_reply_and_block( 72 m, std::chrono::milliseconds(timeout).count()); 73 } 74 } 75 76 template <typename MessageHandler> BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler,void (boost::system::error_code,message))77 inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, 78 void(boost::system::error_code, message)) 79 async_send(implementation_type& impl, message& m, 80 BOOST_ASIO_MOVE_ARG(MessageHandler) handler) { 81 // begin asynchronous operation 82 impl.start(this->get_io_service()); 83 84 boost::asio::detail::async_result_init< 85 MessageHandler, void(boost::system::error_code, message)> 86 init(BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); 87 detail::async_send_op<typename boost::asio::handler_type< 88 MessageHandler, void(boost::system::error_code, message)>::type>( 89 this->get_io_service(), 90 BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler))(impl, m); 91 92 return init.result.get(); 93 } 94 95 private: 96 friend connection; 97 inline void new_match(implementation_type& impl, match& m); 98 99 inline void delete_match(implementation_type& impl, match& m); 100 101 inline void new_filter(implementation_type& impl, filter& f); 102 103 inline void delete_filter(implementation_type& impl, filter& f); 104 }; 105 106 } // namespace dbus 107 108 #endif // DBUS_CONNECTION_SERVICE_HPP 109