Ed Tanous | c9b5521 | 2017-06-12 13:25:51 -0700 | [diff] [blame] | 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 : public boost::asio::detail::service_base<connection_service> { |
| 31 | public: |
| 32 | typedef impl::connection implementation_type; |
| 33 | |
| 34 | inline explicit connection_service(boost::asio::io_service& io) |
| 35 | : boost::asio::detail::service_base<connection_service>(io) {} |
| 36 | |
| 37 | inline void construct(implementation_type& impl) {} |
| 38 | |
| 39 | inline void destroy(implementation_type& impl) {} |
| 40 | |
| 41 | inline void shutdown_service() { |
| 42 | // TODO is there anything that needs shutting down? |
| 43 | } |
| 44 | |
| 45 | inline void open(implementation_type& impl, const string& address) { |
| 46 | boost::asio::io_service& io = this->get_io_service(); |
| 47 | |
| 48 | impl.open(io, address); |
| 49 | } |
| 50 | |
| 51 | inline void open(implementation_type& impl, const int bus = bus::system) { |
| 52 | boost::asio::io_service& io = this->get_io_service(); |
| 53 | |
| 54 | impl.open(io, bus); |
| 55 | } |
| 56 | |
| 57 | inline message send(implementation_type& impl, message& m) { |
| 58 | return impl.send_with_reply_and_block(m); |
| 59 | } |
| 60 | |
| 61 | template <typename Duration> |
| 62 | inline message send(implementation_type& impl, message& m, const Duration& timeout) { |
| 63 | if (timeout == Duration::zero()) { |
| 64 | // TODO this can return false if it failed |
| 65 | impl.send(m); |
| 66 | return message(); |
| 67 | } else { |
| 68 | return impl.send_with_reply_and_block( |
| 69 | m, std::chrono::milliseconds(timeout).count()); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | template <typename MessageHandler> |
| 74 | inline BOOST_ASIO_INITFN_RESULT_TYPE(MessageHandler, |
| 75 | void(boost::system::error_code, message)) |
| 76 | async_send(implementation_type& impl, message& m, |
| 77 | BOOST_ASIO_MOVE_ARG(MessageHandler) handler) { |
| 78 | // begin asynchronous operation |
| 79 | impl.start(this->get_io_service()); |
| 80 | |
| 81 | boost::asio::detail::async_result_init< |
| 82 | MessageHandler, void(boost::system::error_code, message)> |
| 83 | init(BOOST_ASIO_MOVE_CAST(MessageHandler)(handler)); |
| 84 | detail::async_send_op<typename boost::asio::handler_type< |
| 85 | MessageHandler, void(boost::system::error_code, message)>::type>( |
| 86 | this->get_io_service(), |
| 87 | BOOST_ASIO_MOVE_CAST(MessageHandler)(init.handler))(impl, m); |
| 88 | |
| 89 | return init.result.get(); |
| 90 | } |
| 91 | |
| 92 | private: |
| 93 | friend connection; |
| 94 | inline void new_match(implementation_type& impl, match& m); |
| 95 | |
| 96 | inline void delete_match(implementation_type& impl, match& m); |
| 97 | |
| 98 | inline void new_filter(implementation_type& impl, filter& f); |
| 99 | |
| 100 | inline void delete_filter(implementation_type& impl, filter& f); |
| 101 | }; |
| 102 | |
| 103 | } // namespace dbus |
| 104 | |
| 105 | #endif // DBUS_CONNECTION_SERVICE_HPP |