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/intrusive_ptr.hpp>
13
14void intrusive_ptr_add_ref(DBusConnection *c)
15{
16  dbus_connection_ref(c);
17}
18
19void intrusive_ptr_release(DBusConnection *c)
20{
21  dbus_connection_unref(c);
22}
23
24namespace dbus {
25namespace impl {
26
27class connection
28{
29public:
30  boost::intrusive_ptr<DBusConnection> conn;
31  bool is_shared;
32  bool is_paused;
33
34  connection()
35  {
36  }
37
38  connection(boost::asio::io_service& io, int bus, bool shared)
39    : is_shared(shared),
40      is_paused(true)
41  {
42    error e;
43    if(is_shared)
44    {
45      conn = dbus_bus_get((DBusBusType)bus, e);
46    }
47    else
48    {
49      conn = dbus_bus_get_private((DBusBusType)bus, e);
50    }
51    e.throw_if_set();
52
53    dbus_connection_set_exit_on_disconnect(conn.get(), false);
54
55    detail::set_watch_timeout_dispatch_functions(conn.get(), io);
56  }
57
58  connection(boost::asio::io_service& io, const string& address, bool shared)
59    : is_shared(shared),
60      is_paused(true)
61  {
62    error e;
63    if(shared)
64    {
65      conn = dbus_connection_open(address.c_str(), e);
66    }
67    else
68    {
69      conn = dbus_connection_open_private(address.c_str(), e);
70    }
71    e.throw_if_set();
72
73    dbus_bus_register(conn.get(), e);
74    e.throw_if_set();
75
76    dbus_connection_set_exit_on_disconnect(conn.get(), false);
77
78    detail::set_watch_timeout_dispatch_functions(conn.get(), io);
79  }
80
81  ~connection()
82  {
83    if(!is_shared) dbus_connection_close(conn.get());
84  }
85
86  operator DBusConnection *()
87  {
88    return conn.get();
89  }
90  operator const DBusConnection *() const
91  {
92    return conn.get();
93  }
94
95  // begin asynchronous operation
96  //FIXME should not get io from an argument
97  void start(boost::asio::io_service& io)
98  {
99    if(is_paused)
100    {
101      is_paused = false;
102      io.post(detail::dispatch_handler(io, conn.get()));
103    }
104  }
105};
106
107} // namespace impl
108} // namespace dbus
109
110#endif // DBUS_CONNECTION_IPP
111