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_IPP 7#define DBUS_CONNECTION_IPP 8 9#include <dbus/dbus.h> 10#include <dbus/detail/watch_timeout.hpp> 11 12#include <boost/atomic.hpp> 13 14namespace dbus { 15namespace impl { 16 17class connection 18{ 19public: 20 boost::atomic<bool> is_paused; 21 DBusConnection *conn; 22 23 connection() 24 : is_paused(true), 25 conn(NULL) 26 { 27 } 28 29 void open(boost::asio::io_service& io, int bus) 30 { 31 error e; 32 conn = dbus_bus_get_private((DBusBusType)bus, e); 33 e.throw_if_set(); 34 35 dbus_connection_set_exit_on_disconnect(conn, false); 36 37 detail::set_watch_timeout_dispatch_functions(conn, io); 38 } 39 40 void open(boost::asio::io_service& io, const string& address) 41 { 42 error e; 43 conn = dbus_connection_open_private(address.c_str(), e); 44 e.throw_if_set(); 45 46 dbus_bus_register(conn, e); 47 e.throw_if_set(); 48 49 dbus_connection_set_exit_on_disconnect(conn, false); 50 51 detail::set_watch_timeout_dispatch_functions(conn, io); 52 } 53 54 ~connection() 55 { 56 if (conn != NULL) { 57 dbus_connection_close(conn); 58 dbus_connection_unref(conn); 59 } 60 } 61 62 operator DBusConnection *() 63 { 64 return conn; 65 } 66 operator const DBusConnection *() const 67 { 68 return conn; 69 } 70 71 message send_with_reply_and_block(message& m, 72 int timeout_in_milliseconds = -1) 73 { 74 error e; 75 message reply(dbus_connection_send_with_reply_and_block(conn, 76 m, timeout_in_milliseconds, e)); 77 78 e.throw_if_set(); 79 return reply; 80 } 81 82 void send(message& m) 83 { 84 // ignoring message serial for now 85 dbus_connection_send(conn, m, NULL); 86 } 87 88 void send_with_reply(message& m, 89 DBusPendingCall **p, 90 int timeout_in_milliseconds = -1) 91 { 92 dbus_connection_send_with_reply(conn, 93 m, p, timeout_in_milliseconds); 94 } 95 96 // begin asynchronous operation 97 //FIXME should not get io from an argument 98 void start(boost::asio::io_service& io) 99 { 100 bool old_value(true); 101 if(is_paused.compare_exchange_strong(old_value, false)) 102 { 103 // If two threads call connection::async_send() 104 // simultaneously on a paused connection, then 105 // only one will pass the CAS instruction and 106 // only one dispatch_handler will be injected. 107 io.post(detail::dispatch_handler(io, conn)); 108 } 109 } 110 111 void cancel(boost::asio::io_service& io) 112 { 113 bool old_value(false); 114 if(is_paused.compare_exchange_strong(old_value, true)) 115 { 116 //TODO 117 } 118 } 119}; 120 121} // namespace impl 122} // namespace dbus 123 124#endif // DBUS_CONNECTION_IPP 125