blob: 41c8f925d3bac1515a155b6f681b92f65a143bfa [file] [log] [blame]
Ed Tanousc9b55212017-06-12 13:25:51 -07001// 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 public:
19 boost::atomic<bool> is_paused;
20 DBusConnection* conn;
21
22 connection() : is_paused(true), conn(NULL) {}
23
24 void open(boost::asio::io_service& io, int bus) {
25 error e;
26 conn = dbus_bus_get_private((DBusBusType)bus, e);
27 e.throw_if_set();
28
29 dbus_connection_set_exit_on_disconnect(conn, false);
30
31 detail::set_watch_timeout_dispatch_functions(conn, io);
32 }
33
34 void open(boost::asio::io_service& io, const string& address) {
35 error e;
36 conn = dbus_connection_open_private(address.c_str(), e);
37 e.throw_if_set();
38
39 dbus_bus_register(conn, e);
40 e.throw_if_set();
41
42 dbus_connection_set_exit_on_disconnect(conn, false);
43
44 detail::set_watch_timeout_dispatch_functions(conn, io);
45 }
46
Ed Tanous5fceeb42017-06-28 09:43:09 -070047 void request_name(const string& name) {
48 error e;
49 dbus_bus_request_name(conn, name.c_str(),
50 DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_REPLACE_EXISTING, e);
51 e.throw_if_set();
52 }
53
Ed Tanous3dac7492017-08-02 13:46:20 -070054 std::string get_unique_name() {
55 error e;
56 auto name = dbus_bus_get_unique_name (conn);
57 e.throw_if_set();
58 return std::string(name);
59 }
60
Ed Tanousc9b55212017-06-12 13:25:51 -070061 ~connection() {
62 if (conn != NULL) {
63 dbus_connection_close(conn);
64 dbus_connection_unref(conn);
65 }
66 }
67
Ed Tanous5fceeb42017-06-28 09:43:09 -070068 message new_method_return(message &m) {
69 return dbus_message_new_method_return(m);
70 }
71
Ed Tanousc9b55212017-06-12 13:25:51 -070072 operator DBusConnection*() { return conn; }
73 operator const DBusConnection*() const { return conn; }
74
75 message send_with_reply_and_block(message& m,
76 int timeout_in_milliseconds = -1) {
77 error e;
78 DBusMessage* out = dbus_connection_send_with_reply_and_block(
79 conn, m, timeout_in_milliseconds, e);
80 e.throw_if_set();
81 message reply(out);
82
83 return reply;
84 }
85
86 void send(message& m) {
87 // ignoring message serial for now
88 dbus_connection_send(conn, m, NULL);
89 }
90
91 void send_with_reply(message& m, DBusPendingCall** p,
92 int timeout_in_milliseconds = -1) {
93 dbus_connection_send_with_reply(conn, 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 bool old_value(true);
100 if (is_paused.compare_exchange_strong(old_value, false)) {
101 // If two threads call connection::async_send()
102 // simultaneously on a paused connection, then
103 // only one will pass the CAS instruction and
104 // only one dispatch_handler will be injected.
105 io.post(detail::dispatch_handler(io, conn));
106 }
107 }
108
109 void cancel(boost::asio::io_service& io) {
110 bool old_value(false);
111 if (is_paused.compare_exchange_strong(old_value, true)) {
112 // TODO
113 }
114 }
115};
116
117} // namespace impl
118} // namespace dbus
119
120#endif // DBUS_CONNECTION_IPP