1a3cc3d57SBenjamin Kietzman// Copyright (c) Benjamin Kietzman (github.com/bkietz) 2a3cc3d57SBenjamin Kietzman// 3a3cc3d57SBenjamin Kietzman// Distributed under the Boost Software License, Version 1.0. (See accompanying 4a3cc3d57SBenjamin Kietzman// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5a3cc3d57SBenjamin Kietzman 6a3cc3d57SBenjamin Kietzman#ifndef DBUS_CONNECTION_IPP 7a3cc3d57SBenjamin Kietzman#define DBUS_CONNECTION_IPP 8a3cc3d57SBenjamin Kietzman 9a3cc3d57SBenjamin Kietzman#include <dbus/dbus.h> 10a3cc3d57SBenjamin Kietzman#include <dbus/detail/watch_timeout.hpp> 11a3cc3d57SBenjamin Kietzman 12cfc0655fSBenjamin Kietzman#include <boost/atomic.hpp> 13a3cc3d57SBenjamin Kietzman 14a3cc3d57SBenjamin Kietzmannamespace dbus { 15a3cc3d57SBenjamin Kietzmannamespace impl { 16a3cc3d57SBenjamin Kietzman 17da3eeb6aSEd Tanousclass connection { 18a3cc3d57SBenjamin Kietzman public: 19cfc0655fSBenjamin Kietzman boost::atomic<bool> is_paused; 20*77e62c83SEd Tanous 21*77e62c83SEd Tanous private: 22cfc0655fSBenjamin Kietzman DBusConnection* conn; 23a3cc3d57SBenjamin Kietzman 24*77e62c83SEd Tanous public: 25da3eeb6aSEd Tanous connection() : is_paused(true), conn(NULL) {} 26a3cc3d57SBenjamin Kietzman 27*77e62c83SEd Tanous connection(const connection& other) = delete; // non construction-copyable 28*77e62c83SEd Tanous connection& operator=(const connection&) = delete; // non copyable 29*77e62c83SEd Tanous connection(connection&&) = delete; 30*77e62c83SEd Tanous connection& operator=(connection&&) = delete; 31*77e62c83SEd Tanous 32da3eeb6aSEd Tanous void open(boost::asio::io_service& io, int bus) { 33a3cc3d57SBenjamin Kietzman error e; 34a3cc3d57SBenjamin Kietzman conn = dbus_bus_get_private((DBusBusType)bus, e); 35a3cc3d57SBenjamin Kietzman e.throw_if_set(); 36a3cc3d57SBenjamin Kietzman 37cfc0655fSBenjamin Kietzman dbus_connection_set_exit_on_disconnect(conn, false); 38a3cc3d57SBenjamin Kietzman 39cfc0655fSBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(conn, io); 40a3cc3d57SBenjamin Kietzman } 41a3cc3d57SBenjamin Kietzman 42da3eeb6aSEd Tanous void open(boost::asio::io_service& io, const string& address) { 43a3cc3d57SBenjamin Kietzman error e; 44a3cc3d57SBenjamin Kietzman conn = dbus_connection_open_private(address.c_str(), e); 452003615dSBenjamin Kietzman e.throw_if_set(); 46a3cc3d57SBenjamin Kietzman 47cfc0655fSBenjamin Kietzman dbus_bus_register(conn, e); 48a3cc3d57SBenjamin Kietzman e.throw_if_set(); 49a3cc3d57SBenjamin Kietzman 50cfc0655fSBenjamin Kietzman dbus_connection_set_exit_on_disconnect(conn, false); 51a3cc3d57SBenjamin Kietzman 52cfc0655fSBenjamin Kietzman detail::set_watch_timeout_dispatch_functions(conn, io); 53a3cc3d57SBenjamin Kietzman } 54a3cc3d57SBenjamin Kietzman 55458a9c10SVernon Mauery void request_name(const string& name) { 56458a9c10SVernon Mauery error e; 57*77e62c83SEd Tanous dbus_bus_request_name( 58*77e62c83SEd Tanous conn, name.c_str(), 59458a9c10SVernon Mauery DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_REPLACE_EXISTING, e); 60458a9c10SVernon Mauery e.throw_if_set(); 61458a9c10SVernon Mauery } 62458a9c10SVernon Mauery 630d6f56d2SEd Tanous std::string get_unique_name() { 640d6f56d2SEd Tanous error e; 650d6f56d2SEd Tanous auto name = dbus_bus_get_unique_name(conn); 660d6f56d2SEd Tanous e.throw_if_set(); 670d6f56d2SEd Tanous return std::string(name); 680d6f56d2SEd Tanous } 690d6f56d2SEd Tanous 70da3eeb6aSEd Tanous ~connection() { 718f81b71dSBenjamin Kietzman if (conn != NULL) { 72cfc0655fSBenjamin Kietzman dbus_connection_close(conn); 73cfc0655fSBenjamin Kietzman dbus_connection_unref(conn); 74a3cc3d57SBenjamin Kietzman } 758f81b71dSBenjamin Kietzman } 76a3cc3d57SBenjamin Kietzman 77458a9c10SVernon Mauery message new_method_return(message& m) { 78*77e62c83SEd Tanous auto ptr = dbus_message_new_method_return(m); 79*77e62c83SEd Tanous auto x = message(ptr); 80*77e62c83SEd Tanous dbus_message_unref(ptr); 81*77e62c83SEd Tanous return x; 82458a9c10SVernon Mauery } 83458a9c10SVernon Mauery 84da3eeb6aSEd Tanous operator DBusConnection*() { return conn; } 85da3eeb6aSEd Tanous operator const DBusConnection*() const { return conn; } 86a3cc3d57SBenjamin Kietzman 87b55ed5d5SBenjamin Kietzman message send_with_reply_and_block(message& m, 88da3eeb6aSEd Tanous int timeout_in_milliseconds = -1) { 89b55ed5d5SBenjamin Kietzman error e; 90*77e62c83SEd Tanous 91da3eeb6aSEd Tanous DBusMessage* out = dbus_connection_send_with_reply_and_block( 92da3eeb6aSEd Tanous conn, m, timeout_in_milliseconds, e); 93*77e62c83SEd Tanous 94b55ed5d5SBenjamin Kietzman e.throw_if_set(); 95da3eeb6aSEd Tanous message reply(out); 96*77e62c83SEd Tanous dbus_message_unref(out); 97b55ed5d5SBenjamin Kietzman return reply; 98b55ed5d5SBenjamin Kietzman } 99b55ed5d5SBenjamin Kietzman 100da3eeb6aSEd Tanous void send(message& m) { 101b55ed5d5SBenjamin Kietzman // ignoring message serial for now 102b55ed5d5SBenjamin Kietzman dbus_connection_send(conn, m, NULL); 103b55ed5d5SBenjamin Kietzman } 104b55ed5d5SBenjamin Kietzman 105da3eeb6aSEd Tanous void send_with_reply(message& m, DBusPendingCall** p, 106da3eeb6aSEd Tanous int timeout_in_milliseconds = -1) { 107da3eeb6aSEd Tanous dbus_connection_send_with_reply(conn, m, p, timeout_in_milliseconds); 108b55ed5d5SBenjamin Kietzman } 109b55ed5d5SBenjamin Kietzman 1102003615dSBenjamin Kietzman // begin asynchronous operation 1112003615dSBenjamin Kietzman // FIXME should not get io from an argument 112da3eeb6aSEd Tanous void start(boost::asio::io_service& io) { 113cfc0655fSBenjamin Kietzman bool old_value(true); 114da3eeb6aSEd Tanous if (is_paused.compare_exchange_strong(old_value, false)) { 115cfc0655fSBenjamin Kietzman // If two threads call connection::async_send() 116cfc0655fSBenjamin Kietzman // simultaneously on a paused connection, then 117cfc0655fSBenjamin Kietzman // only one will pass the CAS instruction and 118cfc0655fSBenjamin Kietzman // only one dispatch_handler will be injected. 119cfc0655fSBenjamin Kietzman io.post(detail::dispatch_handler(io, conn)); 120cfc0655fSBenjamin Kietzman } 121cfc0655fSBenjamin Kietzman } 122cfc0655fSBenjamin Kietzman 123da3eeb6aSEd Tanous void cancel(boost::asio::io_service& io) { 124cfc0655fSBenjamin Kietzman bool old_value(false); 125da3eeb6aSEd Tanous if (is_paused.compare_exchange_strong(old_value, true)) { 126cfc0655fSBenjamin Kietzman // TODO 1272003615dSBenjamin Kietzman } 128a3cc3d57SBenjamin Kietzman } 129a3cc3d57SBenjamin Kietzman}; 130a3cc3d57SBenjamin Kietzman 131a3cc3d57SBenjamin Kietzman} // namespace impl 132a3cc3d57SBenjamin Kietzman} // namespace dbus 133a3cc3d57SBenjamin Kietzman 134a3cc3d57SBenjamin Kietzman#endif // DBUS_CONNECTION_IPP 135