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