Merge lp:~mhr3/unity/ubus-rewrite into lp:unity

Proposed by Michal Hruby
Status: Merged
Approved by: Gord Allott
Approved revision: no longer in the source branch.
Merged at revision: 2838
Proposed branch: lp:~mhr3/unity/ubus-rewrite
Merge into: lp:unity
Diff against target: 1805 lines (+624/-745)
28 files modified
UnityCore/Variant.cpp (+13/-1)
UnityCore/Variant.h (+2/-0)
dash/DashController.cpp (+4/-3)
dash/DashController.h (+1/-0)
dash/DashView.cpp (+2/-1)
dash/PlacesGroup.cpp (+1/-1)
dash/ResultViewGrid.cpp (+1/-1)
launcher/ApplicationLauncherIcon.cpp (+0/-1)
launcher/LauncherController.cpp (+2/-1)
launcher/LauncherIcon.cpp (+2/-3)
launcher/QuicklistManager.cpp (+2/-3)
launcher/QuicklistView.cpp (+3/-7)
launcher/SimpleLauncherIcon.cpp (+2/-3)
launcher/Tooltip.cpp (+2/-3)
plugins/unityshell/src/UnityGestureTarget.cpp (+2/-4)
plugins/unityshell/src/unity-root-accessible.cpp (+3/-1)
plugins/unityshell/src/unityshell.cpp (+1/-0)
tests/CMakeLists.txt (+4/-3)
tests/test_ubus.cpp (+327/-0)
tests/unit/TestMain.cpp (+0/-2)
tests/unit/TestUBus.cpp (+0/-157)
unity-shared/CMakeLists.txt (+1/-1)
unity-shared/UBusServer.cpp (+120/-0)
unity-shared/UBusServer.h (+71/-0)
unity-shared/UBusWrapper.cpp (+42/-49)
unity-shared/UBusWrapper.h (+16/-23)
unity-shared/ubus-server.cpp (+0/-397)
unity-shared/ubus-server.h (+0/-80)
To merge this branch: bzr merge lp:~mhr3/unity/ubus-rewrite
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Andrea Azzarone (community) Approve
jenkins continuous-integration Pending
Review via email: mp+127821@code.launchpad.net

Commit message

Rewrite UBus

Description of the change

Remove last bit of good old GObject code and replace it with C++ version of UBus, the only additional feature atm is the ability to specify priority when sending UBus messages. Besides that change the API stayed pretty much the same (with the exception of using glib::Variant instead of raw GVariant*).

The default priority of messages was also bumped to DEFAULT (instead of DEFAULT_IDLE), to try to prevent issues like lp:1064256 (arguably it might be good idea to lower the prio once unity isn't running in the same thread as compiz, but for now this will be better default).

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Overall it looks good. I haven't had the time to do much testing, but I tried to fix that launcher showing to slowly and there seems to be another bug located in that...

Ill spend some more time running tests and playing around with this some more :)

Thanks!

Revision history for this message
Andrea Azzarone (azzar1) wrote :

966 +UBusServer::~UBusServer()
967 +{
968 +}

Remove it please. It should not be required.

5 + for (auto it = interests_.begin(); it != interests_.end(); ++it)
986 + {
987 + if ((*it).second->id == connection_id)
988 + {
989 + interests_.erase(it);
990 + return;
991 + }
992 + }

Can you use the range-based for loop of std::erase + std::remove_if?

995 +void UBusServer::SendMessage(std::string const& message_name,
996 + glib::Variant const& args)
997 +{
998 + SendMessageFull(message_name, args, glib::Source::Priority::DEFAULT_IDLE);
999 +}
1000 +
1001 +void UBusServer::SendMessageFull(std::string const& message_name,
1002 + glib::Variant const& args,
1003 + glib::Source::Priority prio)
1004 +{

What about default value here?

+ msg_queue_.insert(std::pair<int, std::pair<std::string, glib::Variant>>(prio, std::pair<std::string, glib::Variant>(message_name, args)));

ouch :) std::make_pair will make this line shorter :)

1009 + auto src_nick = boost::lexical_cast<std::string>(static_cast<int>(prio));

std::to_string should be good :)

1088 +#include <vector>
1089 +#include <boost/utility.hpp>

I think these are not needed.

1221 + // we don't want to modify a container while iterating it
1222 + std::set<unsigned> ids_copy(connection_ids_);
1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
1224 + {
1225 + UnregisterInterest(*it);
1226 + }

IIRC std::set::erase does not invalidate all the iterators of the container, but just the iterator of the erased element. So you can avoid std::set<unsigned> ids_copy(connection_ids_); doing somethign like this:

for (...) {
  auto to_delete = it;
  it++; // don't do this above too :)
  UnregisterInterest(*to_delete);
}

But i'm not really sure about this :)

1274 +#include <map>

Should not be necessary.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

1006 + msg_queue_.insert(std::pair<int, std::pair<std::string, glib::Variant>>(prio, std::pair<std::string, glib::Variant>(message_name, args)));

It can be just std::make_pair(prio, std::make_pair(message_name, args))

1009 + auto src_nick = boost::lexical_cast<std::string>(static_cast<int>(prio));

No need for it with C++11, just use std::to_string(prio); also use auto const& when possible.

985 + for (auto it = interests_.begin(); it != interests_.end(); ++it)

Not tried, but I guess that also the multimaps, would handle nicely a for (auto const& : interests_) foreach loop.

983 +void UBusServer::UnregisterInterest(unsigned connection_id)

I know this is safer, but what's the reason why not to add also UBusServer::UnregisterInterest(std::string const& name) as it used to be?
[NVM, I've noticed that now there's only just one static UBusServer: +1].

1034 + for (unsigned i = 0; i < dispatched_msgs.size(); i++)

Use ++i or just a foreach loop.

1221 + // we don't want to modify a container while iterating it
1222 + std::set<unsigned> ids_copy(connection_ids_);
1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
1224 + {
1225 + UnregisterInterest(*it);
1226 + }

this is also safe:
for (auto it = ids_copy.begin(); it != ids_copy.end();)
{
  UnregisterInterest(*(it++));
}

1317 + static std::unique_ptr<UBusServer> server;

You can just use an stack allocated server here, just remember to add this to the .cpp file:
// initialize the global static server
UBusServer UBusManager::server;

PS: add yourself to to authors, so people will bother you when on troubles ;-D

Revision history for this message
Michal Hruby (mhr3) wrote :

> Remove it please. It should not be required.

Done

> Can you use the range-based for loop of std::erase + std::remove_if?

remove_if traverses the entire collection, I know there's just one item with the given id, so used find_if + erase instead.

> What about default value here?

It's *Full because the default param-variant is SendMessage().

> ouch :) std::make_pair will make this line shorter :)

Fixed.

> std::to_string should be good :)

Fixed.

> I think these are not needed.

Removed.

> IIRC std::set::erase does not invalidate all the iterators of the container,
> but just the iterator of the erased element. So you can avoid
> std::set<unsigned> ids_copy(connection_ids_); doing somethign like this:
> ...

The Unregister calls can lead to more Unregister calls (destroying a signal handler can lead to destruction of another object that will call Unregister in its own destructor), it's safer to try to call Unregister with already unregistered id, than to use invalid iterator.

>
> 1274 +#include <map>
>
> Should not be necessary.

Removed.

Revision history for this message
Michal Hruby (mhr3) wrote :

> 1034 + for (unsigned i = 0; i < dispatched_msgs.size(); i++)
>
> Use ++i or just a foreach loop.

It's 2012, compilers do that these days ;) (plus it's simple type, so there's no ambiguity)

>
> 1221 + // we don't want to modify a container while iterating it
> 1222 + std::set<unsigned> ids_copy(connection_ids_);
> 1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
> 1224 + {
> 1225 + UnregisterInterest(*it);
> 1226 + }
>
> this is also safe:
> for (auto it = ids_copy.begin(); it != ids_copy.end();)
> {
> UnregisterInterest(*(it++));
> }

True, but it looks weird :P

>
> 1317 + static std::unique_ptr<UBusServer> server;
>
> You can just use an stack allocated server here, just remember to add this to
> the .cpp file:
> // initialize the global static server
> UBusServer UBusManager::server;

I'd rather keep it this way, it allows lazy initialization (even though not used now).

> PS: add yourself to to authors, so people will bother you when on troubles ;-D

Done.

Revision history for this message
Andrea Azzarone (azzar1) wrote :

> 966 +UBusServer::~UBusServer()
> 967 +{
> 968 +}
>
> Remove it please. It should not be required.
>
> 5 + for (auto it = interests_.begin(); it != interests_.end(); ++it)
> 986 + {
> 987 + if ((*it).second->id == connection_id)
> 988 + {
> 989 + interests_.erase(it);
> 990 + return;
> 991 + }
> 992 + }
>
> Can you use the range-based for loop of std::erase + std::remove_if?
>
> 995 +void UBusServer::SendMessage(std::string const& message_name,
> 996 + glib::Variant const& args)
> 997 +{
> 998 + SendMessageFull(message_name, args,
> glib::Source::Priority::DEFAULT_IDLE);
> 999 +}
> 1000 +
> 1001 +void UBusServer::SendMessageFull(std::string const& message_name,
> 1002 + glib::Variant const& args,
> 1003 + glib::Source::Priority prio)
> 1004 +{

I mean you ca do:

class UbusServer {
...
   void SendMessage(std::string const& message_name, glib::Variant const& args, glib::Source::Priority prio = DEFAULT_IDLE)
...
}

So you don't need two functions. But this is not blocking.

>
> What about default value here?
>
> + msg_queue_.insert(std::pair<int, std::pair<std::string,
> glib::Variant>>(prio, std::pair<std::string, glib::Variant>(message_name,
> args)));
>
> ouch :) std::make_pair will make this line shorter :)
>
> 1009 + auto src_nick =
> boost::lexical_cast<std::string>(static_cast<int>(prio));
>
> std::to_string should be good :)
>
> 1088 +#include <vector>
> 1089 +#include <boost/utility.hpp>
>
> I think these are not needed.
>
> 1221 + // we don't want to modify a container while iterating it
> 1222 + std::set<unsigned> ids_copy(connection_ids_);
> 1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
> 1224 + {
> 1225 + UnregisterInterest(*it);
> 1226 + }
>
> IIRC std::set::erase does not invalidate all the iterators of the container,
> but just the iterator of the erased element. So you can avoid
> std::set<unsigned> ids_copy(connection_ids_); doing somethign like this:
>
> for (...) {
> auto to_delete = it;
> it++; // don't do this above too :)
> UnregisterInterest(*to_delete);
> }
>
> But i'm not really sure about this :)
>
> 1274 +#include <map>
>
> Should not be necessary.

review: Approve
Revision history for this message
Michal Hruby (mhr3) wrote :

> void SendMessage(std::string const& message_name, glib::Variant const&
> args, glib::Source::Priority prio = DEFAULT_IDLE)
> ...
> }
>
> So you don't need two functions. But this is not blocking.

Right, fwiw UBusManager is doing that, and noone should be using the server directly.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looks nice now, thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/Variant.cpp'
2--- UnityCore/Variant.cpp 2012-08-22 15:02:29 +0000
3+++ UnityCore/Variant.cpp 2012-10-12 08:42:18 +0000
4@@ -31,7 +31,7 @@
5 Variant::Variant(GVariant* variant)
6 : variant_(variant)
7 {
8- g_variant_ref_sink(variant_);
9+ if (variant) g_variant_ref_sink(variant_);
10 }
11
12 Variant::Variant(GVariant* variant, StealRef const& ref)
13@@ -95,6 +95,11 @@
14 return true;
15 }
16
17+void Variant::swap(Variant& other)
18+{
19+ std::swap(this->variant_, other.variant_);
20+}
21+
22 Variant& Variant::operator=(GVariant* val)
23 {
24 if (variant_) g_variant_unref(variant_);
25@@ -103,6 +108,13 @@
26 return *this;
27 }
28
29+Variant& Variant::operator=(Variant other)
30+{
31+ swap(other);
32+
33+ return *this;
34+}
35+
36 Variant::operator GVariant* () const
37 {
38 return variant_;
39
40=== modified file 'UnityCore/Variant.h'
41--- UnityCore/Variant.h 2012-08-22 15:02:29 +0000
42+++ UnityCore/Variant.h 2012-10-12 08:42:18 +0000
43@@ -53,7 +53,9 @@
44
45 bool ASVToHints(HintsMap& hints) const;
46
47+ void swap(Variant&);
48 Variant& operator=(GVariant*);
49+ Variant& operator=(Variant);
50 operator GVariant*() const;
51 operator bool() const;
52
53
54=== modified file 'dash/DashController.cpp'
55--- dash/DashController.cpp 2012-10-04 07:10:39 +0000
56+++ dash/DashController.cpp 2012-10-12 08:42:18 +0000
57@@ -137,7 +137,7 @@
58
59 window_->UpdateInputWindowGeometry();
60
61- ubus_manager_.UnregisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST);
62+ ubus_manager_.UnregisterInterest(place_entry_request_id_);
63 }
64
65 void Controller::RegisterUBusInterests()
66@@ -146,8 +146,9 @@
67 sigc::mem_fun(this, &Controller::OnExternalShowDash));
68 ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_CLOSE_REQUEST,
69 sigc::mem_fun(this, &Controller::OnExternalHideDash));
70- ubus_manager_.RegisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
71- sigc::mem_fun(this, &Controller::OnActivateRequest));
72+ place_entry_request_id_ =
73+ ubus_manager_.RegisterInterest(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
74+ sigc::mem_fun(this, &Controller::OnActivateRequest));
75 ubus_manager_.RegisterInterest(UBUS_DASH_ABOUT_TO_SHOW,
76 [&] (GVariant*) { EnsureDash(); });
77 ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, [&] (GVariant *data)
78
79=== modified file 'dash/DashController.h'
80--- dash/DashController.h 2012-09-18 17:39:36 +0000
81+++ dash/DashController.h 2012-10-12 08:42:18 +0000
82@@ -108,6 +108,7 @@
83 Animator timeline_animator_;
84 UBusManager ubus_manager_;
85 unsigned int dbus_owner_;
86+ unsigned place_entry_request_id_;
87 glib::Object<GCancellable> dbus_connect_cancellable_;
88 static GDBusInterfaceVTable interface_vtable;
89 };
90
91=== modified file 'dash/DashView.cpp'
92--- dash/DashView.cpp 2012-10-05 12:51:56 +0000
93+++ dash/DashView.cpp 2012-10-12 08:42:18 +0000
94@@ -829,7 +829,8 @@
95 }
96 else if (/* visible_ && */ handled_type == NOT_HANDLED)
97 {
98- ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
99+ ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST, NULL,
100+ glib::Source::Priority::HIGH);
101 }
102 else if (/* visible_ && */ handled_type == GOTO_DASH_URI)
103 {
104
105=== modified file 'dash/PlacesGroup.cpp'
106--- dash/PlacesGroup.cpp 2012-10-08 06:36:17 +0000
107+++ dash/PlacesGroup.cpp 2012-10-12 08:42:18 +0000
108@@ -31,7 +31,7 @@
109 #include <UnityCore/GLibWrapper.h>
110
111 #include "unity-shared/StaticCairoText.h"
112-#include "unity-shared/ubus-server.h"
113+#include "unity-shared/UBusWrapper.h"
114 #include "unity-shared/UBusMessages.h"
115
116
117
118=== modified file 'dash/ResultViewGrid.cpp'
119--- dash/ResultViewGrid.cpp 2012-10-03 11:09:27 +0000
120+++ dash/ResultViewGrid.cpp 2012-10-12 08:42:18 +0000
121@@ -31,7 +31,7 @@
122 #include <UnityCore/Variant.h>
123 #include "unity-shared/IntrospectableWrappers.h"
124 #include "unity-shared/Timer.h"
125-#include "unity-shared/ubus-server.h"
126+#include "unity-shared/UBusWrapper.h"
127 #include "unity-shared/UBusMessages.h"
128 #include "ResultViewGrid.h"
129 #include "math.h"
130
131=== modified file 'launcher/ApplicationLauncherIcon.cpp'
132--- launcher/ApplicationLauncherIcon.cpp 2012-10-04 08:00:29 +0000
133+++ launcher/ApplicationLauncherIcon.cpp 2012-10-12 08:42:18 +0000
134@@ -33,7 +33,6 @@
135 #include "Launcher.h"
136 #include "MultiMonitor.h"
137 #include "unity-shared/UBusMessages.h"
138-#include "unity-shared/ubus-server.h"
139
140 #include <glib/gi18n-lib.h>
141 #include <gio/gdesktopappinfo.h>
142
143=== modified file 'launcher/LauncherController.cpp'
144--- launcher/LauncherController.cpp 2012-10-10 16:38:42 +0000
145+++ launcher/LauncherController.cpp 2012-10-12 08:42:18 +0000
146@@ -951,7 +951,8 @@
147
148 void Controller::Impl::SendHomeActivationRequest()
149 {
150- ubus.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST, g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, ""));
151+ ubus.SendMessage(UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
152+ g_variant_new("(sus)", "home.lens", dash::NOT_HANDLED, ""));
153 }
154
155 Controller::Controller()
156
157=== modified file 'launcher/LauncherIcon.cpp'
158--- launcher/LauncherIcon.cpp 2012-10-04 07:10:39 +0000
159+++ launcher/LauncherIcon.cpp 2012-10-12 08:42:18 +0000
160@@ -44,7 +44,7 @@
161
162 #include "MultiMonitor.h"
163
164-#include "unity-shared/ubus-server.h"
165+#include "unity-shared/UBusWrapper.h"
166 #include "unity-shared/UBusMessages.h"
167 #include <UnityCore/GLibWrapper.h>
168 #include <UnityCore/Variant.h>
169@@ -865,8 +865,7 @@
170 Present(0.5f, 1500);
171 }
172
173- UBusServer* ubus = ubus_server_get_default();
174- ubus_server_send_message(ubus, UBUS_LAUNCHER_ICON_URGENT_CHANGED, g_variant_new_boolean(value));
175+ UBusManager::SendMessage(UBUS_LAUNCHER_ICON_URGENT_CHANGED, g_variant_new_boolean(value));
176 }
177
178 if (quirk == Quirk::VISIBLE)
179
180=== modified file 'launcher/QuicklistManager.cpp'
181--- launcher/QuicklistManager.cpp 2012-05-07 19:52:54 +0000
182+++ launcher/QuicklistManager.cpp 2012-10-12 08:42:18 +0000
183@@ -25,7 +25,7 @@
184 #include "QuicklistView.h"
185 #include "QuicklistManager.h"
186
187-#include "unity-shared/ubus-server.h"
188+#include "unity-shared/UBusWrapper.h"
189 #include "unity-shared/UBusMessages.h"
190
191 namespace unity
192@@ -109,8 +109,7 @@
193 _current_quicklist = quicklist;
194
195 quicklist_opened.emit(quicklist);
196- UBusServer* ubus = ubus_server_get_default();
197- ubus_server_send_message(ubus, UBUS_QUICKLIST_SHOWN, NULL);
198+ UBusManager::SendMessage(UBUS_QUICKLIST_SHOWN);
199 }
200
201 void QuicklistManager::RecvHideQuicklist(nux::BaseWindow* window)
202
203=== modified file 'launcher/QuicklistView.cpp'
204--- launcher/QuicklistView.cpp 2012-09-27 11:47:36 +0000
205+++ launcher/QuicklistView.cpp 2012-10-12 08:42:18 +0000
206@@ -42,7 +42,7 @@
207 #include "unity-shared/Introspectable.h"
208 #include "unity-shared/UnitySettings.h"
209
210-#include "unity-shared/ubus-server.h"
211+#include "unity-shared/UBusWrapper.h"
212 #include "unity-shared/UBusMessages.h"
213 #include "unity-shared/DashStyle.h"
214
215@@ -281,18 +281,14 @@
216 case NUX_KP_LEFT:
217 Hide();
218 // inform Launcher we switch back to Launcher key-nav
219- ubus_server_send_message(ubus_server_get_default(),
220- UBUS_QUICKLIST_END_KEY_NAV,
221- NULL);
222+ UBusManager::SendMessage(UBUS_QUICKLIST_END_KEY_NAV);
223 break;
224
225 // esc (close quicklist, exit key-nav)
226 case NUX_VK_ESCAPE:
227 Hide();
228 // inform UnityScreen we leave key-nav completely
229- ubus_server_send_message(ubus_server_get_default(),
230- UBUS_LAUNCHER_END_KEY_NAV,
231- NULL);
232+ UBusManager::SendMessage(UBUS_LAUNCHER_END_KEY_NAV);
233 break;
234
235 // <SPACE>, <RETURN> (activate selected menu-item)
236
237=== modified file 'launcher/SimpleLauncherIcon.cpp'
238--- launcher/SimpleLauncherIcon.cpp 2012-10-04 07:10:39 +0000
239+++ launcher/SimpleLauncherIcon.cpp 2012-10-12 08:42:18 +0000
240@@ -27,7 +27,7 @@
241
242 #include "SimpleLauncherIcon.h"
243
244-#include "unity-shared/ubus-server.h"
245+#include "unity-shared/UBusWrapper.h"
246 #include "unity-shared/UBusMessages.h"
247
248 namespace unity
249@@ -92,8 +92,7 @@
250 void SimpleLauncherIcon::ActivateLauncherIcon(ActionArg arg)
251 {
252 activate.emit();
253- ubus_server_send_message(ubus_server_get_default(),
254- UBUS_PLACE_VIEW_CLOSE_REQUEST,
255+ UBusManager::SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST,
256 g_variant_new_boolean(FALSE));
257 }
258
259
260=== modified file 'launcher/Tooltip.cpp'
261--- launcher/Tooltip.cpp 2012-09-25 17:02:59 +0000
262+++ launcher/Tooltip.cpp 2012-10-12 08:42:18 +0000
263@@ -24,7 +24,7 @@
264 #include <UnityCore/Variant.h>
265
266 #include "unity-shared/CairoTexture.h"
267-#include "unity-shared/ubus-server.h"
268+#include "unity-shared/UBusWrapper.h"
269 #include "unity-shared/UBusMessages.h"
270 #include <unity-shared/UnitySettings.h>
271
272@@ -103,8 +103,7 @@
273 PushToFront();
274
275 ShowWindow(true);
276- UBusServer* ubus = ubus_server_get_default();
277- ubus_server_send_message(ubus, UBUS_TOOLTIP_SHOWN, NULL);
278+ UBusManager::SendMessage(UBUS_TOOLTIP_SHOWN);
279 }
280
281 void Tooltip::Draw(nux::GraphicsEngine& gfxContext, bool forceDraw)
282
283=== modified file 'plugins/unityshell/src/UnityGestureTarget.cpp'
284--- plugins/unityshell/src/UnityGestureTarget.cpp 2012-07-27 20:24:01 +0000
285+++ plugins/unityshell/src/UnityGestureTarget.cpp 2012-10-12 08:42:18 +0000
286@@ -27,7 +27,7 @@
287 #include "Launcher.h"
288
289 #include "UBusMessages.h"
290-#include "ubus-server.h"
291+#include "UBusWrapper.h"
292
293 using namespace nux;
294
295@@ -46,9 +46,7 @@
296 else if (event.GetGestureClasses() == TAP_GESTURE
297 && event.type == EVENT_GESTURE_END)
298 {
299- ubus_server_send_message(ubus_server_get_default(),
300- UBUS_DASH_EXTERNAL_ACTIVATION,
301- NULL);
302+ UBusManager::SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);
303 }
304
305 return GestureDeliveryRequest::NONE;
306
307=== modified file 'plugins/unityshell/src/unity-root-accessible.cpp'
308--- plugins/unityshell/src/unity-root-accessible.cpp 2012-10-11 16:17:09 +0000
309+++ plugins/unityshell/src/unity-root-accessible.cpp 2012-10-12 08:42:18 +0000
310@@ -30,6 +30,8 @@
311 #include "nux-base-window-accessible.h"
312 #include "unitya11y.h"
313
314+#include <UnityCore/Variant.h>
315+
316 #include "UBusWrapper.h"
317 #include "UBusMessages.h"
318
319@@ -352,7 +354,7 @@
320 }
321
322 static void
323-ubus_launcher_register_interest_cb(GVariant* variant,
324+ubus_launcher_register_interest_cb(unity::glib::Variant const& variant,
325 UnityRootAccessible* self)
326 {
327 //launcher window is the same during all the life of Unity
328
329=== modified file 'plugins/unityshell/src/unityshell.cpp'
330--- plugins/unityshell/src/unityshell.cpp 2012-10-10 18:10:34 +0000
331+++ plugins/unityshell/src/unityshell.cpp 2012-10-12 08:42:18 +0000
332@@ -59,6 +59,7 @@
333 #include "unitya11y.h"
334
335 #include "UBusMessages.h"
336+#include "UBusWrapper.h"
337 #include "UScreen.h"
338
339 #include "config.h"
340
341=== modified file 'tests/CMakeLists.txt'
342--- tests/CMakeLists.txt 2012-10-09 09:48:07 +0000
343+++ tests/CMakeLists.txt 2012-10-12 08:42:18 +0000
344@@ -63,14 +63,12 @@
345 add_executable (test-unit
346 unit/TestMain.cpp
347 unit/TestPanelService.cpp
348- unit/TestUBus.cpp
349 unit/TestStaticCairoText.cpp
350 ${CMAKE_SOURCE_DIR}/launcher/CairoBaseWindow.cpp
351 ${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
352 ${CMAKE_SOURCE_DIR}/unity-shared/StaticCairoText.cpp
353 ../services/panel-service.c
354 ${CMAKE_CURRENT_BINARY_DIR}/panel-marshal.c
355- ${CMAKE_SOURCE_DIR}/unity-shared/ubus-server.cpp
356 )
357 target_link_libraries (test-unit unity-shared ${LIBS})
358 add_dependencies (test-unit unity-core-${UNITY_API_VERSION})
359@@ -149,6 +147,7 @@
360 test_shortcut_model.cpp
361 test_shortcut_private.cpp
362 test_showdesktop_handler.cpp
363+ test_ubus.cpp
364 test_unityshell_private.cpp
365 ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp
366 ${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
367@@ -168,6 +167,8 @@
368 ${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
369 ${CMAKE_SOURCE_DIR}/unity-shared/TextureCache.cpp
370 ${CMAKE_SOURCE_DIR}/unity-shared/Timer.cpp
371+ ${CMAKE_SOURCE_DIR}/unity-shared/UBusServer.cpp
372+ ${CMAKE_SOURCE_DIR}/unity-shared/UBusWrapper.cpp
373 ${UNITY_SRC}/UnityshellPrivate.cpp
374 ${CMAKE_SOURCE_DIR}/unity-shared/WindowManager.cpp
375 ${CMAKE_SOURCE_DIR}/unity-shared/StandaloneWindowManager.cpp
376@@ -356,6 +357,7 @@
377 ${CMAKE_SOURCE_DIR}/unity-shared/Timer.cpp
378 ${CMAKE_SOURCE_DIR}/unity-shared/TextureThumbnailProvider.cpp
379 ${CMAKE_SOURCE_DIR}/unity-shared/ThumbnailGenerator.cpp
380+ ${CMAKE_SOURCE_DIR}/unity-shared/UBusServer.cpp
381 ${CMAKE_SOURCE_DIR}/unity-shared/UBusWrapper.cpp
382 ${CMAKE_SOURCE_DIR}/unity-shared/UScreen.cpp
383 ${CMAKE_SOURCE_DIR}/unity-shared/UnitySettings.cpp
384@@ -364,7 +366,6 @@
385 ${CMAKE_SOURCE_DIR}/unity-shared/UserThumbnailProvider.cpp
386 ${CMAKE_SOURCE_DIR}/unity-shared/WindowManager.cpp
387 ${CMAKE_SOURCE_DIR}/unity-shared/XKeyboardUtil.cpp
388- ${CMAKE_SOURCE_DIR}/unity-shared/ubus-server.cpp
389 ${CMAKE_SOURCE_DIR}/plugins/unityshell/src/WindowMinimizeSpeedController.cpp
390 )
391 target_link_libraries(test-gtest gtest gmock unity-shared ${LIBS})
392
393=== added file 'tests/test_ubus.cpp'
394--- tests/test_ubus.cpp 1970-01-01 00:00:00 +0000
395+++ tests/test_ubus.cpp 2012-10-12 08:42:18 +0000
396@@ -0,0 +1,327 @@
397+/*
398+ * Copyright 2012 Canonical Ltd.
399+ *
400+ * This program is free software: you can redistribute it and/or modify it
401+ * under the terms of the GNU General Public License version 3, as published
402+ * by the Free Software Foundation.
403+ *
404+ * This program is distributed in the hope that it will be useful, but
405+ * WITHOUT ANY WARRANTY; without even the implied warranties of
406+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
407+ * PURPOSE. See the GNU General Public License for more details.
408+ *
409+ * You should have received a copy of the GNU General Public License
410+ * version 3 along with this program. If not, see
411+ * <http://www.gnu.org/licenses/>
412+ *
413+ * Authored by: Michal Hruby <michal.hruby@canonical.com>
414+ *
415+ */
416+
417+#include <gtest/gtest.h>
418+#include <time.h>
419+#include "TimeUtil.h"
420+#include "test_utils.h"
421+
422+#include <UnityCore/Variant.h>
423+#include <UnityCore/GLibSource.h>
424+#include "UBusServer.h"
425+#include "UBusWrapper.h"
426+
427+#define MESSAGE1 "TEST MESSAGE ONE"
428+#define MESSAGE2 "ՄᕅᏆⲤꙨႧΈ Ϊટ ಗשׁຣ໐ɱË‼‼❢"
429+
430+using namespace unity;
431+
432+namespace
433+{
434+
435+struct TestUBusServer : public testing::Test
436+{
437+ UBusServer ubus_server;
438+ bool callback_called;
439+ unsigned callback_call_count;
440+ glib::Variant last_msg_variant;
441+
442+ virtual void SetUp()
443+ {
444+ callback_called = false;
445+ callback_call_count = 0;
446+ }
447+
448+ void Callback(glib::Variant const& message)
449+ {
450+ callback_called = true;
451+ callback_call_count++;
452+
453+ last_msg_variant = message;
454+ }
455+
456+ void ProcessMessages()
457+ {
458+ bool expired = false;
459+ glib::Idle idle([&] { expired = true; return false; },
460+ glib::Source::Priority::LOW);
461+ Utils::WaitUntil(expired);
462+ }
463+};
464+
465+struct TestUBusManager : public testing::Test
466+{
467+ UBusManager ubus_manager;
468+ bool callback_called;
469+ unsigned callback_call_count;
470+ glib::Variant last_msg_variant;
471+
472+ virtual void SetUp()
473+ {
474+ callback_called = false;
475+ callback_call_count = 0;
476+ }
477+
478+ void Callback(glib::Variant const& message)
479+ {
480+ callback_called = true;
481+ callback_call_count++;
482+
483+ last_msg_variant = message;
484+ }
485+
486+ void ProcessMessages()
487+ {
488+ bool expired = false;
489+ glib::Idle idle([&] { expired = true; return false; },
490+ glib::Source::Priority::LOW);
491+ Utils::WaitUntil(expired);
492+ }
493+};
494+
495+// UBus tests
496+
497+TEST_F(TestUBusServer, Contruct)
498+{
499+ EXPECT_FALSE(callback_called);
500+}
501+
502+TEST_F(TestUBusServer, SingleDispatch)
503+{
504+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
505+ ubus_server.SendMessage(MESSAGE1);
506+
507+ ProcessMessages();
508+
509+ EXPECT_TRUE(callback_called);
510+ EXPECT_EQ(callback_call_count, 1);
511+}
512+
513+TEST_F(TestUBusServer, SingleDispatchWithData)
514+{
515+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
516+ ubus_server.SendMessage(MESSAGE1, g_variant_new_string("UserData"));
517+
518+ ProcessMessages();
519+
520+ EXPECT_TRUE(callback_called);
521+ EXPECT_EQ(callback_call_count, 1);
522+ EXPECT_EQ(last_msg_variant.GetString(), "UserData");
523+}
524+
525+TEST_F(TestUBusServer, SingleDispatchUnicode)
526+{
527+ ubus_server.RegisterInterest(MESSAGE2, sigc::mem_fun(this, &TestUBusServer::Callback));
528+ ubus_server.SendMessage(MESSAGE2);
529+
530+ ProcessMessages();
531+
532+ EXPECT_TRUE(callback_called);
533+ EXPECT_EQ(callback_call_count, 1);
534+}
535+
536+TEST_F(TestUBusServer, SendUnregisteredMessage)
537+{
538+ ubus_server.SendMessage(MESSAGE1);
539+
540+ ProcessMessages();
541+ EXPECT_FALSE(callback_called);
542+}
543+
544+TEST_F(TestUBusServer, SendUninterestedMessage)
545+{
546+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
547+ ubus_server.SendMessage(MESSAGE2);
548+
549+ ProcessMessages();
550+ EXPECT_FALSE(callback_called);
551+}
552+
553+TEST_F(TestUBusServer, MultipleDispatches)
554+{
555+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
556+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
557+ ubus_server.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusServer::Callback));
558+ ubus_server.SendMessage(MESSAGE1);
559+
560+ ProcessMessages();
561+ EXPECT_TRUE(callback_called);
562+ EXPECT_EQ(callback_call_count, 3);
563+}
564+
565+TEST_F(TestUBusServer, MultipleDispatchesWithData)
566+{
567+ int cb_count = 0;
568+ ubus_server.RegisterInterest(MESSAGE1, [&cb_count] (glib::Variant const& data)
569+ {
570+ cb_count++;
571+ EXPECT_EQ(data.GetString(), "foo");
572+ });
573+ ubus_server.RegisterInterest(MESSAGE1, [&cb_count] (glib::Variant const& data)
574+ {
575+ cb_count++;
576+ EXPECT_EQ(data.GetString(), "foo");
577+ });
578+ ubus_server.SendMessage(MESSAGE2);
579+ ubus_server.SendMessage(MESSAGE1, g_variant_new_string("foo"));
580+
581+ ProcessMessages();
582+ EXPECT_EQ(cb_count, 2);
583+}
584+
585+TEST_F(TestUBusServer, DispatchesInOrder)
586+{
587+ std::string order;
588+
589+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
590+ { order += "1"; });
591+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
592+ { order += "2"; });
593+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
594+ { order += "3"; });
595+ ubus_server.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
596+ { order += "4"; });
597+
598+ ubus_server.SendMessage(MESSAGE1);
599+ ubus_server.SendMessage(MESSAGE2);
600+
601+ ProcessMessages();
602+ EXPECT_EQ(order, "1234");
603+
604+ // prepare for second round of dispatches
605+ order = "";
606+
607+ ubus_server.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
608+ { order += "5"; });
609+
610+ // swap order of the messages
611+ ubus_server.SendMessage(MESSAGE2);
612+ ubus_server.SendMessage(MESSAGE1);
613+
614+ ProcessMessages();
615+ EXPECT_EQ(order, "45123");
616+}
617+
618+TEST_F(TestUBusServer, DispatchesWithPriority)
619+{
620+ std::string order;
621+
622+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
623+ { order += "1"; });
624+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
625+ { order += "2"; });
626+ ubus_server.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
627+ { order += "3"; });
628+ ubus_server.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
629+ { order += "4"; });
630+ ubus_server.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
631+ { order += "5"; });
632+
633+ glib::Variant data;
634+ ubus_server.SendMessage(MESSAGE1, data);
635+ ubus_server.SendMessageFull(MESSAGE2, data, glib::Source::Priority::HIGH);
636+
637+ ProcessMessages();
638+ EXPECT_EQ(order, "45123");
639+}
640+
641+TEST_F(TestUBusManager, RegisterAndSend)
642+{
643+ ubus_manager.RegisterInterest(MESSAGE1, sigc::mem_fun(this, &TestUBusManager::Callback));
644+
645+ UBusManager::SendMessage(MESSAGE1);
646+
647+ ProcessMessages();
648+ EXPECT_TRUE(callback_called);
649+ EXPECT_EQ(callback_call_count, 1);
650+}
651+
652+TEST_F(TestUBusManager, Unregister)
653+{
654+ auto interest_id = ubus_manager.RegisterInterest(MESSAGE1,
655+ sigc::mem_fun(this, &TestUBusManager::Callback));
656+
657+ UBusManager::SendMessage(MESSAGE1);
658+
659+ ubus_manager.UnregisterInterest(interest_id);
660+
661+ ProcessMessages();
662+ EXPECT_FALSE(callback_called);
663+}
664+
665+TEST_F(TestUBusManager, AutoUnregister)
666+{
667+ if (true)
668+ {
669+ // want this to go out of scope
670+ UBusManager manager;
671+
672+ manager.RegisterInterest(MESSAGE1,
673+ sigc::mem_fun(this, &TestUBusManager::Callback));
674+ }
675+
676+ UBusManager::SendMessage(MESSAGE1);
677+
678+ ProcessMessages();
679+ EXPECT_FALSE(callback_called);
680+}
681+
682+TEST_F(TestUBusManager, UnregisterInsideCallback)
683+{
684+ unsigned interest_id;
685+ interest_id = ubus_manager.RegisterInterest(MESSAGE1, [&] (glib::Variant const& data)
686+ {
687+ callback_called = true;
688+ callback_call_count++;
689+ ubus_manager.UnregisterInterest(interest_id);
690+ });
691+
692+ UBusManager::SendMessage(MESSAGE1);
693+ UBusManager::SendMessage(MESSAGE1);
694+
695+ ProcessMessages();
696+ EXPECT_TRUE(callback_called);
697+ EXPECT_EQ(callback_call_count, 1);
698+}
699+
700+TEST_F(TestUBusManager, DispatchWithPriority)
701+{
702+ std::string order;
703+
704+ ubus_manager.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
705+ { order += "1"; });
706+ ubus_manager.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
707+ { order += "2"; });
708+ ubus_manager.RegisterInterest(MESSAGE1, [&order] (glib::Variant const&)
709+ { order += "3"; });
710+ ubus_manager.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
711+ { order += "4"; });
712+ ubus_manager.RegisterInterest(MESSAGE2, [&order] (glib::Variant const&)
713+ { order += "5"; });
714+
715+ glib::Variant data;
716+ UBusManager::SendMessage(MESSAGE1, data);
717+ UBusManager::SendMessage(MESSAGE2, data, glib::Source::Priority::HIGH);
718+
719+ ProcessMessages();
720+ EXPECT_EQ(order, "45123");
721+}
722+
723+}
724
725=== modified file 'tests/unit/TestMain.cpp'
726--- tests/unit/TestMain.cpp 2012-08-15 02:51:33 +0000
727+++ tests/unit/TestMain.cpp 2012-10-12 08:42:18 +0000
728@@ -26,7 +26,6 @@
729 #include "Nux/WindowThread.h"
730
731 void TestPanelServiceCreateSuite();
732-void TestUBusCreateSuite();
733 void TestStaticCairoTextCreateSuite();
734
735 nux::WindowThread*
736@@ -71,7 +70,6 @@
737 //Keep alphabetical please
738 TestPanelServiceCreateSuite();
739 TestStaticCairoTextCreateSuite();
740- TestUBusCreateSuite();
741
742 nux::WindowThread* thread = createThread();
743
744
745=== removed file 'tests/unit/TestUBus.cpp'
746--- tests/unit/TestUBus.cpp 2011-07-21 14:59:25 +0000
747+++ tests/unit/TestUBus.cpp 1970-01-01 00:00:00 +0000
748@@ -1,157 +0,0 @@
749-/*
750- * Copyright 2010 Canonical Ltd.
751- *
752- * This program is free software: you can redistribute it and/or modify it
753- * under the terms of the GNU General Public License version 3, as published
754- * by the Free Software Foundation.
755- *
756- * This program is distributed in the hope that it will be useful, but
757- * WITHOUT ANY WARRANTY; without even the implied warranties of
758- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
759- * PURPOSE. See the GNU General Public License for more details.
760- *
761- * You should have received a copy of the GNU General Public License
762- * version 3 along with this program. If not, see
763- * <http://www.gnu.org/licenses/>
764- *
765- * Authored by: Gordon Allott <gord.allott@canonical.com>
766- *
767- */
768-
769-
770-#include "config.h"
771-#include "ubus-server.h"
772-
773-#define MESSAGE1 "TEST MESSAGE ONE"
774-#define MESSAGE2 "ՄᕅᏆⲤꙨႧΈ Ϊટ ಗשׁຣ໐ɱË‼‼❢"
775-
776-static void TestAllocation(void);
777-static void TestMainLoop(void);
778-static void TestPropagation(void);
779-
780-void
781-TestUBusCreateSuite()
782-{
783-#define _DOMAIN "/Unit/UBus"
784- g_test_add_func(_DOMAIN"/Allocation", TestAllocation);
785- g_test_add_func(_DOMAIN"/Propagation", TestPropagation);
786- g_test_add_func(_DOMAIN"/MainLoop", TestMainLoop);
787-}
788-
789-static void
790-TestAllocation()
791-{
792- UBusServer* serv_1 = ubus_server_get_default();
793- UBusServer* serv_2 = ubus_server_get_default();
794-
795- g_assert(serv_1 != NULL);
796- g_assert(serv_2 != NULL);
797-
798- // i used a different way of making a singleton than i am used to
799- // so i'm not 100% confident in it yet
800- g_assert(serv_1 == serv_2);
801-}
802-
803-void
804-test_handler_inc_counter(GVariant* data, gpointer val)
805-{
806- // inc a counter when we get called
807- gint* counter = (gint*)val;
808- *counter = *counter + 1;
809-}
810-
811-void
812-test_handler_inc_counter_2(GVariant* data, gpointer val)
813-{
814- // inc a counter by two when called
815- gint* counter = (gint*)val;
816- *counter = *counter + 2;
817-}
818-
819-static void
820-TestPropagation()
821-{
822- UBusServer* ubus;
823- gint counter, i;
824- guint handler1, handler2;
825-
826- ubus = ubus_server_get_default();
827- handler1 = ubus_server_register_interest(ubus, MESSAGE1,
828- test_handler_inc_counter,
829- &counter);
830-
831- handler2 = ubus_server_register_interest(ubus, MESSAGE2, // tests UNICODE
832- test_handler_inc_counter_2,
833- &counter);
834-
835- counter = 0;
836- for (i = 0; i < 1000; i++)
837- {
838- ubus_server_send_message(ubus, MESSAGE1, NULL);
839- }
840-
841- ubus_server_force_message_pump(ubus);
842-
843- counter = 0;
844- for (i = 0; i < 1000; i++)
845- {
846- ubus_server_send_message(ubus, MESSAGE1, NULL);
847- ubus_server_send_message(ubus, MESSAGE2, NULL);
848- }
849- ubus_server_force_message_pump(ubus);
850-
851- g_assert(counter == 3000);
852-
853- ubus_server_unregister_interest(ubus, handler1);
854- ubus_server_unregister_interest(ubus, handler2);
855-
856- counter = 0;
857- ubus_server_send_message(ubus, MESSAGE1, NULL);
858- ubus_server_send_message(ubus, MESSAGE2, NULL);
859-
860- ubus_server_force_message_pump(ubus);
861-
862- g_assert(counter == 0);
863-}
864-
865-gboolean
866-main_loop_bailout(gpointer data)
867-{
868- GMainLoop* mainloop = (GMainLoop*)data;
869- g_main_quit(mainloop);
870- return FALSE;
871-}
872-
873-void
874-test_handler_mainloop(GVariant* data, gpointer val)
875-{
876- // inc a counter when we get called
877- gint* counter = (gint*)val;
878- *counter = *counter + 1;
879-
880-}
881-
882-static void
883-TestMainLoop()
884-{
885- GMainLoop* mainloop;
886- UBusServer* ubus;
887- gint counter = 0;
888-
889- ubus = ubus_server_get_default();
890- mainloop = g_main_loop_new(NULL, TRUE);
891-
892- g_timeout_add_seconds(1, main_loop_bailout, mainloop);
893-
894- ubus_server_register_interest(ubus, MESSAGE1,
895- test_handler_mainloop,
896- &counter);
897-
898- ubus_server_send_message(ubus, MESSAGE1, NULL);
899- g_main_loop_run(mainloop);
900-
901- g_assert(counter == 1);
902-
903-}
904-
905-
906
907=== modified file 'unity-shared/CMakeLists.txt'
908--- unity-shared/CMakeLists.txt 2012-10-04 07:36:35 +0000
909+++ unity-shared/CMakeLists.txt 2012-10-12 08:42:18 +0000
910@@ -56,6 +56,7 @@
911 TextureThumbnailProvider.cpp
912 ThumbnailGenerator.cpp
913 Timer.cpp
914+ UBusServer.cpp
915 UBusWrapper.cpp
916 UScreen.cpp
917 UnitySettings.cpp
918@@ -65,7 +66,6 @@
919 WindowManager.cpp
920 XKeyboardUtil.cpp
921 XWindowManager.cpp
922- ubus-server.cpp
923 )
924
925 add_library (unity-shared STATIC ${UNITY_SHARED_SOURCES})
926
927=== added file 'unity-shared/UBusServer.cpp'
928--- unity-shared/UBusServer.cpp 1970-01-01 00:00:00 +0000
929+++ unity-shared/UBusServer.cpp 2012-10-12 08:42:18 +0000
930@@ -0,0 +1,120 @@
931+/*
932+ * Copyright (C) 2012 Canonical Ltd
933+ *
934+ * This program is free software: you can redistribute it and/or modify
935+ * it under the terms of the GNU General Public License version 3 as
936+ * published by the Free Software Foundation.
937+ *
938+ * This program is distributed in the hope that it will be useful,
939+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
940+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
941+ * GNU General Public License for more details.
942+ *
943+ * You should have received a copy of the GNU General Public License
944+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
945+ *
946+ * Authored by: Michal Hruby <michal.hruby@canonical.com>
947+ */
948+
949+#include <NuxCore/Logger.h>
950+
951+#include "UBusServer.h"
952+
953+namespace unity
954+{
955+
956+namespace
957+{
958+nux::logging::Logger logger("unity.ubus");
959+}
960+
961+UBusServer::UBusServer()
962+ : last_id_(0)
963+{}
964+
965+unsigned UBusServer::RegisterInterest(std::string const& interest_name,
966+ UBusCallback const& slot)
967+{
968+ if (!slot || interest_name.empty())
969+ return 0;
970+
971+ unsigned connection_id = ++last_id_;
972+ auto connection = std::make_shared<UBusConnection>(slot, connection_id);
973+ interests_.insert(std::pair<std::string, UBusConnection::Ptr>(interest_name, connection));
974+
975+ return connection_id;
976+}
977+
978+void UBusServer::UnregisterInterest(unsigned connection_id)
979+{
980+ auto it = std::find_if(interests_.begin(), interests_.end(),
981+ [&] (std::pair<std::string, UBusConnection::Ptr> const& p)
982+ { return p.second->id == connection_id; });
983+ if (it != interests_.end()) interests_.erase(it);
984+}
985+
986+void UBusServer::SendMessage(std::string const& message_name,
987+ glib::Variant const& args)
988+{
989+ SendMessageFull(message_name, args, glib::Source::Priority::DEFAULT_IDLE);
990+}
991+
992+void UBusServer::SendMessageFull(std::string const& message_name,
993+ glib::Variant const& args,
994+ glib::Source::Priority prio)
995+{
996+ // queue the message
997+ msg_queue_.insert(std::pair<int, std::pair<std::string, glib::Variant>>(prio, std::make_pair(message_name, args)));
998+
999+ // start the source (if not already running)
1000+ auto src_nick = std::to_string(static_cast<int>(prio));
1001+ auto src_ptr = source_manager_.GetSource(src_nick);
1002+ if (!src_ptr)
1003+ {
1004+ source_manager_.Add(new glib::Idle([this, prio] ()
1005+ {
1006+ return DispatchMessages(prio);
1007+ }, prio));
1008+ }
1009+}
1010+
1011+bool UBusServer::DispatchMessages(glib::Source::Priority prio)
1012+{
1013+ // copy messages we are about to dispatch to a separate container
1014+ std::vector<std::pair<std::string, glib::Variant> > dispatched_msgs;
1015+
1016+ auto iterators = msg_queue_.equal_range(prio);
1017+ for (auto it = iterators.first; it != iterators.second; ++it)
1018+ {
1019+ dispatched_msgs.push_back((*it).second);
1020+ }
1021+
1022+ // remove the messages from the queue
1023+ msg_queue_.erase(prio);
1024+
1025+ for (unsigned i = 0; i < dispatched_msgs.size(); i++)
1026+ {
1027+ // invoke callbacks for this message_name
1028+ std::string const& message_name = dispatched_msgs[i].first;
1029+ glib::Variant const& msg_args = dispatched_msgs[i].second;
1030+ auto interest_it = interests_.find(message_name);
1031+ while (interest_it != interests_.end())
1032+ {
1033+ // add a reference to make sure we don't crash if the slot unregisters itself
1034+ UBusConnection::Ptr connection((*interest_it).second);
1035+ interest_it++;
1036+ // invoke the slot
1037+ // FIXME: what if this slot unregisters the next? We should mark the interests map dirty in UnregisterInterest
1038+ connection->slot(msg_args);
1039+
1040+ if (interest_it == interests_.end() ||
1041+ (*interest_it).first != message_name)
1042+ break;
1043+ }
1044+ }
1045+
1046+ // return true if there are new queued messages with this prio
1047+ return msg_queue_.find(prio) != msg_queue_.end();
1048+}
1049+
1050+}
1051
1052=== added file 'unity-shared/UBusServer.h'
1053--- unity-shared/UBusServer.h 1970-01-01 00:00:00 +0000
1054+++ unity-shared/UBusServer.h 2012-10-12 08:42:18 +0000
1055@@ -0,0 +1,71 @@
1056+/*
1057+ * Copyright (C) 2010 Canonical Ltd
1058+ *
1059+ * This program is free software: you can redistribute it and/or modify
1060+ * it under the terms of the GNU General Public License version 3 as
1061+ * published by the Free Software Foundation.
1062+ *
1063+ * This program is distributed in the hope that it will be useful,
1064+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1065+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1066+ * GNU General Public License for more details.
1067+ *
1068+ * You should have received a copy of the GNU General Public License
1069+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1070+ *
1071+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1072+ * Michal Hruby <michal.hruby@canonical.com>
1073+ */
1074+
1075+#ifndef UNITY_UBUS_SERVER_H
1076+#define UNITY_UBUS_SERVER_H
1077+
1078+#include <memory>
1079+#include <string>
1080+#include <map>
1081+
1082+#include <UnityCore/Variant.h>
1083+#include <UnityCore/GLibSource.h>
1084+
1085+namespace unity
1086+{
1087+
1088+typedef std::function<void(glib::Variant const&)> UBusCallback;
1089+
1090+class UBusServer : public boost::noncopyable
1091+{
1092+public:
1093+ UBusServer();
1094+
1095+ unsigned RegisterInterest(std::string const& interest_name,
1096+ UBusCallback const& slot);
1097+ void UnregisterInterest(unsigned connection_id);
1098+ void SendMessage(std::string const& message_name,
1099+ glib::Variant const& args = glib::Variant());
1100+ void SendMessageFull(std::string const& message_name,
1101+ glib::Variant const& args,
1102+ glib::Source::Priority prio);
1103+
1104+private:
1105+ struct UBusConnection
1106+ {
1107+ typedef std::shared_ptr<UBusConnection> Ptr;
1108+
1109+ UBusCallback slot;
1110+ unsigned id;
1111+
1112+ UBusConnection(UBusCallback const& cb, unsigned connection_id)
1113+ : slot(cb), id(connection_id) {}
1114+ };
1115+
1116+ bool DispatchMessages(glib::Source::Priority);
1117+
1118+ unsigned last_id_;
1119+ std::multimap<std::string, UBusConnection::Ptr> interests_;
1120+ std::multimap<int, std::pair<std::string, glib::Variant> > msg_queue_;
1121+ glib::SourceManager source_manager_;
1122+};
1123+
1124+}
1125+
1126+#endif
1127
1128=== modified file 'unity-shared/UBusWrapper.cpp'
1129--- unity-shared/UBusWrapper.cpp 2012-07-16 11:03:32 +0000
1130+++ unity-shared/UBusWrapper.cpp 2012-10-12 08:42:18 +0000
1131@@ -1,5 +1,5 @@
1132 /*
1133- * Copyright (C) 2010 Canonical Ltd
1134+ * Copyright (C) 2012 Canonical Ltd
1135 *
1136 * This program is free software: you can redistribute it and/or modify
1137 * it under the terms of the GNU General Public License version 3 as
1138@@ -13,65 +13,58 @@
1139 * You should have received a copy of the GNU General Public License
1140 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1141 *
1142- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1143+ * Authored by: Michal Hruby <michal.hruby@canonical.com>
1144 */
1145
1146+#include <NuxCore/Logger.h>
1147+
1148 #include "UBusWrapper.h"
1149
1150 namespace unity
1151 {
1152
1153+// initialize the global static ptr
1154+std::unique_ptr<UBusServer> UBusManager::server(new UBusServer());
1155+
1156 UBusManager::UBusManager()
1157- : server_(ubus_server_get_default())
1158-{}
1159+{
1160+}
1161
1162 UBusManager::~UBusManager()
1163 {
1164- for (auto connection: connections_)
1165- {
1166- ubus_server_unregister_interest(server_, connection->id);
1167- }
1168-}
1169-
1170-void UBusManager::RegisterInterest(std::string const& interest_name,
1171- UBusManagerCallback slot)
1172-{
1173- if (!slot || interest_name.empty())
1174- return;
1175-
1176- auto connection = std::make_shared<UBusConnection>();
1177- connection->name = interest_name;
1178- connection->slot = slot;
1179- connection->id = ubus_server_register_interest(server_,
1180- interest_name.c_str(),
1181- UBusManager::OnCallback,
1182- connection.get());
1183- connections_.push_back(connection);
1184-}
1185-
1186-void UBusManager::UnregisterInterest(std::string const& interest_name)
1187-{
1188- for (auto it = connections_.begin(); it != connections_.end(); ++it)
1189- {
1190- if ((*it)->name == interest_name)
1191- {
1192- ubus_server_unregister_interest(server_, (*it)->id);
1193- connections_.erase(it);
1194- break;
1195- }
1196- }
1197-}
1198-
1199-void UBusManager::OnCallback(GVariant* args, gpointer user_data)
1200-{
1201- UBusConnection* connection = static_cast<UBusConnection*>(user_data);
1202-
1203- connection->slot(args);
1204-}
1205-
1206-void UBusManager::SendMessage(std::string const& message_name, GVariant* args)
1207-{
1208- ubus_server_send_message(server_, message_name.c_str(), args);
1209+ // we don't want to modify a container while iterating it
1210+ std::set<unsigned> ids_copy(connection_ids_);
1211+ for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
1212+ {
1213+ UnregisterInterest(*it);
1214+ }
1215+}
1216+
1217+unsigned UBusManager::RegisterInterest(std::string const& interest_name,
1218+ UBusCallback const& slot)
1219+{
1220+ unsigned c_id = server->RegisterInterest(interest_name, slot);
1221+
1222+ if (c_id != 0) connection_ids_.insert(c_id);
1223+
1224+ return c_id;
1225+}
1226+
1227+void UBusManager::UnregisterInterest(unsigned connection_id)
1228+{
1229+ auto it = connection_ids_.find(connection_id);
1230+ if (it != connection_ids_.end())
1231+ {
1232+ server->UnregisterInterest(connection_id);
1233+ connection_ids_.erase(it);
1234+ }
1235+}
1236+
1237+void UBusManager::SendMessage(std::string const& message_name,
1238+ glib::Variant const& args,
1239+ glib::Source::Priority prio)
1240+{
1241+ server->SendMessageFull(message_name, args, prio);
1242 }
1243
1244 }
1245
1246=== modified file 'unity-shared/UBusWrapper.h'
1247--- unity-shared/UBusWrapper.h 2012-07-16 11:03:32 +0000
1248+++ unity-shared/UBusWrapper.h 2012-10-12 08:42:18 +0000
1249@@ -1,5 +1,5 @@
1250 /*
1251- * Copyright (C) 2010 Canonical Ltd
1252+ * Copyright (C) 2010-2012 Canonical Ltd
1253 *
1254 * This program is free software: you can redistribute it and/or modify
1255 * it under the terms of the GNU General Public License version 3 as
1256@@ -14,6 +14,7 @@
1257 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1258 *
1259 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1260+ * Michal Hruby <michal.hruby@canonical.com>
1261 */
1262
1263 #ifndef UNITY_UBUS_WRAPPER_H
1264@@ -21,10 +22,12 @@
1265
1266 #include <memory>
1267 #include <string>
1268-#include <vector>
1269-#include <boost/utility.hpp>
1270-
1271-#include "ubus-server.h"
1272+#include <set>
1273+
1274+#include <UnityCore/Variant.h>
1275+#include <UnityCore/GLibSource.h>
1276+
1277+#include "UBusServer.h"
1278
1279 namespace unity
1280 {
1281@@ -32,29 +35,19 @@
1282 class UBusManager : public boost::noncopyable
1283 {
1284 public:
1285- typedef std::function<void(GVariant*)> UBusManagerCallback;
1286-
1287 UBusManager();
1288 ~UBusManager();
1289
1290- void RegisterInterest(std::string const& interest_name, UBusManagerCallback slot);
1291- void UnregisterInterest(std::string const& interest_name);
1292- void SendMessage(std::string const& message_name, GVariant* args = NULL);
1293+ unsigned RegisterInterest(std::string const& interest_name,
1294+ UBusCallback const& slot);
1295+ void UnregisterInterest(unsigned connection_id);
1296+ static void SendMessage(std::string const& message_name,
1297+ glib::Variant const& args = glib::Variant(),
1298+ glib::Source::Priority prio = glib::Source::Priority::DEFAULT);
1299
1300 private:
1301- struct UBusConnection
1302- {
1303- typedef std::shared_ptr<UBusConnection> Ptr;
1304-
1305- std::string name;
1306- UBusManagerCallback slot;
1307- guint id;
1308- };
1309-
1310- static void OnCallback(GVariant* args, gpointer user_data);
1311-
1312- UBusServer* server_;
1313- std::vector<UBusConnection::Ptr> connections_;
1314+ static std::unique_ptr<UBusServer> server;
1315+ std::set<unsigned> connection_ids_;
1316 };
1317
1318 }
1319
1320=== removed file 'unity-shared/ubus-server.cpp'
1321--- unity-shared/ubus-server.cpp 2012-05-06 23:48:38 +0000
1322+++ unity-shared/ubus-server.cpp 1970-01-01 00:00:00 +0000
1323@@ -1,397 +0,0 @@
1324-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
1325-/*
1326- * u-bus-server.c
1327- * Copyright (C) 2010 Canonical, Ltd.
1328- *
1329- * This library is free software; you can redistribute it and/or modify
1330- * it under the terms of the GNU Lesser General Public License
1331- * version 3.0 as published by the Free Software Foundation.
1332- *
1333- * This library is distributed in the hope that it will be useful,
1334- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1335- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1336- * GNU Lesser General Public License version 3.0 for more details.
1337- *
1338- * You should have received a copy of the GNU Lesser General Public
1339- * License along with this library. If not, see
1340- * <http://www.gnu.org/licenses/>.
1341- *
1342- * Authored by Gordon Allott <gord.allott@canonical.com>
1343- */
1344-
1345-#include "ubus-server.h"
1346-#include <string.h>
1347-#include <stdlib.h>
1348-#include <glib.h>
1349-
1350-#define UBUS_SERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
1351- UBUS_TYPE_SERVER, \
1352- UBusServerPrivate))
1353-
1354-struct _UBusServerPrivate
1355-{
1356- GHashTable* message_interest_table;
1357- GHashTable* dispatch_table;
1358-
1359- GQueue* message_queue;
1360- GStringChunk* message_names;
1361-
1362- guint id_sequencial_number;
1363- gboolean message_pump_queued;
1364-};
1365-
1366-
1367-G_DEFINE_TYPE(UBusServer, ubus_server, G_TYPE_INITIALLY_UNOWNED);
1368-
1369-struct _UBusDispatchInfo
1370-{
1371- guint id;
1372- UBusCallback callback;
1373- gchar* message;
1374- gpointer user_data;
1375-};
1376-typedef struct _UBusDispatchInfo UBusDispatchInfo;
1377-
1378-UBusDispatchInfo*
1379-ubus_dispatch_info_new(UBusServer* server,
1380- const gchar* message,
1381- UBusCallback callback,
1382- gpointer user_data)
1383-{
1384- g_return_val_if_fail(UBUS_IS_SERVER(server), NULL);
1385- UBusServerPrivate* priv = server->priv;
1386- UBusDispatchInfo* info;
1387-
1388- if (priv->id_sequencial_number < 1)
1389- {
1390- g_critical(G_STRLOC ": ID's are overflowing");
1391- }
1392-
1393- info = g_slice_new(UBusDispatchInfo);
1394- info->id = priv->id_sequencial_number++;
1395- info->callback = callback;
1396- info->message = g_string_chunk_insert_const(priv->message_names, message);
1397- info->user_data = user_data;
1398-
1399- return info;
1400-}
1401-
1402-void
1403-ubus_dispatch_info_free(UBusDispatchInfo* info)
1404-{
1405- g_slice_free(UBusDispatchInfo, info);
1406-}
1407-
1408-struct _UBusMessageInfo
1409-{
1410- gchar* message;
1411- GVariant* data;
1412-};
1413-
1414-typedef struct _UBusMessageInfo UBusMessageInfo;
1415-
1416-/*
1417- * If @data is floating the constructed message info will
1418- * assume ownership of the ref.
1419- *
1420- * The message member of the UBusMessageInfo struct is managed
1421- * by the UBusServer owning the message. This is done to have
1422- * "interned" strings representing the message names.
1423- *
1424- * Technically the interning is done with g_string_chunk_insert_const().
1425- * This not only gives us imporved memory management, but also allows
1426- * us to compare message names with direct pointer comparison.
1427- */
1428-static UBusMessageInfo*
1429-ubus_message_info_new(GVariant* data)
1430-{
1431- UBusMessageInfo* info;
1432-
1433- info = g_slice_new0(UBusMessageInfo);
1434- info->data = data;
1435-
1436- if (data != NULL)
1437- g_variant_ref_sink(data);
1438-
1439- return info;
1440-}
1441-
1442-static void
1443-ubus_message_info_free(UBusMessageInfo* info)
1444-{
1445- if (info->data != NULL)
1446- {
1447- g_variant_unref(info->data);
1448- info->data = NULL;
1449- }
1450-
1451- g_slice_free(UBusMessageInfo, info);
1452-}
1453-
1454-static void
1455-ubus_server_init(UBusServer* server)
1456-{
1457- UBusServerPrivate* priv;
1458-
1459- priv = server->priv = UBUS_SERVER_GET_PRIVATE(server);
1460-
1461- /* message_interest_table holds the message/DispatchInfo relationship
1462- * We can use g_direct_* hash functions because we are interning all
1463- * message names in our GStringChunk
1464- */
1465- priv->message_interest_table = g_hash_table_new_full(g_direct_hash,
1466- g_direct_equal,
1467- NULL,
1468- (GDestroyNotify) g_sequence_free);
1469- // dispatch_table holds the individial id/DispatchInfo pairs
1470- priv->dispatch_table = g_hash_table_new_full(g_direct_hash,
1471- g_direct_equal,
1472- NULL,
1473- (GDestroyNotify) ubus_dispatch_info_free);
1474-
1475- // for anyone thats wondering (hi kamstrup!), there are two hash tables so
1476- // that lookups are fast when sending messages and removing handlers
1477-
1478- priv->message_queue = g_queue_new();
1479- priv->message_names = g_string_chunk_new(512);
1480- priv->id_sequencial_number = 1;
1481-}
1482-
1483-static void
1484-ubus_server_finalize(GObject* object)
1485-{
1486- UBusServer* server;
1487- UBusServerPrivate* priv;
1488-
1489- server = UBUS_SERVER(object);
1490- priv = server->priv;
1491-
1492- g_hash_table_destroy(priv->message_interest_table);
1493- g_hash_table_destroy(priv->dispatch_table);
1494-
1495- UBusMessageInfo* info = (UBusMessageInfo*)g_queue_pop_tail(priv->message_queue);
1496- for (; info != NULL; info = (UBusMessageInfo*)g_queue_pop_tail(priv->message_queue))
1497- {
1498- ubus_message_info_free(info);
1499- }
1500-
1501- g_queue_free(priv->message_queue);
1502- g_string_chunk_free(priv->message_names);
1503-
1504- G_OBJECT_CLASS(ubus_server_parent_class)->finalize(object);
1505-}
1506-
1507-static void
1508-ubus_server_class_init(UBusServerClass* klass)
1509-{
1510- GObjectClass* object_class = G_OBJECT_CLASS(klass);
1511- g_type_class_add_private(klass, sizeof(UBusServerPrivate));
1512- object_class->finalize = ubus_server_finalize;
1513-}
1514-
1515-UBusServer*
1516-ubus_server_get_default()
1517-{
1518- UBusServer* server;
1519- static gsize singleton;
1520-
1521- // Ensure GType has been initialized
1522- g_type_init();
1523-
1524- if (g_once_init_enter(&singleton))
1525- {
1526- server = (UBusServer*)g_object_new(UBUS_TYPE_SERVER, NULL);
1527- g_object_ref_sink(server);
1528- g_once_init_leave(&singleton, (gsize) server);
1529- }
1530-
1531- // we actually just want to hold our own reference and not let anything
1532- // else reference us, because we never want to lose that reference, we are
1533- // only allowed to initalise once
1534- return (UBusServer*)singleton;
1535-}
1536-
1537-guint
1538-ubus_server_register_interest(UBusServer* server,
1539- const gchar* message,
1540- UBusCallback callback,
1541- gpointer user_data)
1542-{
1543- UBusServerPrivate* priv;
1544- GSequence* dispatch_list;
1545- gchar* interned_message;
1546- UBusDispatchInfo* info;
1547-
1548- g_return_val_if_fail(UBUS_IS_SERVER(server), 0);
1549- g_return_val_if_fail(message != NULL, 0);
1550-
1551- priv = server->priv;
1552- interned_message = g_string_chunk_insert_const(priv->message_names, message);
1553- dispatch_list = (GSequence*)g_hash_table_lookup(priv->message_interest_table,
1554- interned_message);
1555-
1556- if (dispatch_list == NULL)
1557- {
1558- // not had this message before so add a new entry to the message_interest table
1559- dispatch_list = g_sequence_new(NULL); // we use a sequence because its a stable pointer
1560- g_hash_table_insert(priv->message_interest_table,
1561- interned_message,
1562- dispatch_list);
1563- }
1564-
1565- // add the callback to the dispatch table
1566- info = ubus_dispatch_info_new(server, message, callback, user_data);
1567- g_hash_table_insert(priv->dispatch_table, GUINT_TO_POINTER(info->id), info);
1568-
1569- // add the dispatch info to the dispatch list in the message interest table
1570- g_sequence_append(dispatch_list, info);
1571-
1572- return info->id;
1573-}
1574-
1575-static gboolean
1576-ubus_server_pump_message_queue(UBusServer* server)
1577-{
1578- g_return_val_if_fail(UBUS_IS_SERVER(server), FALSE);
1579- UBusServerPrivate* priv = server->priv;
1580- UBusMessageInfo* info;
1581-
1582- priv->message_pump_queued = FALSE;
1583-
1584- // loop through each message queued and call the dispatch functions associated
1585- // with it. something in the back of my mind says it would be quicker in some
1586- // situations to sort the queue first so that duplicate messages can re-use
1587- // the same dispatch_list lookups.. but thats a specific case.
1588-
1589- info = (UBusMessageInfo*)g_queue_pop_tail(priv->message_queue);
1590- for (; info != NULL; info = (UBusMessageInfo*)g_queue_pop_tail(priv->message_queue))
1591- {
1592- GSequence* dispatch_list;
1593- dispatch_list = (GSequence*)g_hash_table_lookup(priv->message_interest_table,
1594- info->message);
1595-
1596- if (dispatch_list == NULL)
1597- {
1598- ubus_message_info_free(info);
1599- continue; // no handlers for this message
1600- }
1601-
1602- GSequenceIter* iter = g_sequence_get_begin_iter(dispatch_list);
1603- GSequenceIter* end = g_sequence_get_end_iter(dispatch_list);
1604-
1605- while (iter != end)
1606- {
1607- GSequenceIter* next = g_sequence_iter_next(iter);
1608- UBusDispatchInfo* dispatch_info = (UBusDispatchInfo*)g_sequence_get(iter);
1609- UBusCallback callback = dispatch_info->callback;
1610-
1611- (*callback)(info->data, dispatch_info->user_data);
1612-
1613- iter = next;
1614- }
1615-
1616- ubus_message_info_free(info);
1617- }
1618-
1619- return FALSE;
1620-}
1621-
1622-static void
1623-ubus_server_queue_message_pump(UBusServer* server)
1624-{
1625- UBusServerPrivate* priv;
1626-
1627- g_return_if_fail(UBUS_IS_SERVER(server));
1628-
1629- priv = server->priv;
1630- if (priv->message_pump_queued)
1631- return;
1632-
1633- g_idle_add((GSourceFunc)ubus_server_pump_message_queue, server);
1634- priv->message_pump_queued = TRUE;
1635-}
1636-
1637-void
1638-ubus_server_send_message(UBusServer* server,
1639- const gchar* message,
1640- GVariant* data)
1641-{
1642- UBusServerPrivate* priv;
1643- UBusMessageInfo* message_info;
1644-
1645- g_return_if_fail(UBUS_IS_SERVER(server));
1646- g_return_if_fail(message != NULL);
1647-
1648- priv = server->priv;
1649- message_info = ubus_message_info_new(data);
1650- message_info->message = g_string_chunk_insert_const(priv->message_names,
1651- message);
1652-
1653- g_queue_push_head(priv->message_queue, message_info);
1654- ubus_server_queue_message_pump(server);
1655-}
1656-
1657-void
1658-ubus_server_unregister_interest(UBusServer* server, guint handle)
1659-{
1660- UBusServerPrivate* priv;
1661- GSequence* dispatch_list;
1662- UBusDispatchInfo* info;
1663-
1664- g_return_if_fail(UBUS_IS_SERVER(server));
1665- g_return_if_fail(handle > 0);
1666-
1667- priv = server->priv;
1668- info = (UBusDispatchInfo*)g_hash_table_lookup(priv->dispatch_table, GUINT_TO_POINTER(handle));
1669-
1670- if (info == NULL)
1671- {
1672- g_warning(G_STRLOC ": Handle %u does not exist", handle);
1673- return;
1674- }
1675-
1676- // now the slightly sucky bit, we have to remove from our message-interest
1677- // table, but we can only find it by itterating through a sequence
1678- // but this is not so bad because we know *which* sequence its in
1679-
1680- dispatch_list = (GSequence*)g_hash_table_lookup(priv->message_interest_table,
1681- info->message);
1682-
1683- if (dispatch_list == NULL)
1684- {
1685- g_critical(G_STRLOC ": Handle exists but not dispatch list, ubus has "\
1686- "become unstable");
1687- return;
1688- }
1689-
1690- GSequenceIter* iter = g_sequence_get_begin_iter(dispatch_list);
1691- GSequenceIter* end = g_sequence_get_end_iter(dispatch_list);
1692- while (iter != end)
1693- {
1694- GSequenceIter* next = g_sequence_iter_next(iter);
1695- UBusDispatchInfo* info_test = (UBusDispatchInfo*)g_sequence_get(iter);
1696-
1697- if (info_test->id == handle)
1698- {
1699- g_sequence_remove(iter);
1700- }
1701-
1702- iter = next;
1703- }
1704-
1705- if (g_sequence_get_length(dispatch_list) == 0)
1706- {
1707- // free the key/value pair
1708- g_hash_table_remove(priv->message_interest_table, info->message);
1709- }
1710-
1711- // finally remove the dispatch_table hash table.
1712- g_hash_table_remove(priv->dispatch_table, &handle);
1713-
1714-}
1715-
1716-void
1717-ubus_server_force_message_pump(UBusServer* server)
1718-{
1719- ubus_server_pump_message_queue(server);
1720-}
1721
1722=== removed file 'unity-shared/ubus-server.h'
1723--- unity-shared/ubus-server.h 2012-05-06 23:48:38 +0000
1724+++ unity-shared/ubus-server.h 1970-01-01 00:00:00 +0000
1725@@ -1,80 +0,0 @@
1726-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
1727-/*
1728- * u-bus-server.h
1729- * Copyright (C) 2010 Canonical, Ltd.
1730- *
1731- * This library is free software; you can redistribute it and/or modify
1732- * it under the terms of the GNU Lesser General Public License
1733- * version 3.0 as published by the Free Software Foundation.
1734- *
1735- * This library is distributed in the hope that it will be useful,
1736- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1737- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1738- * GNU Lesser General Public License version 3.0 for more details.
1739- *
1740- * You should have received a copy of the GNU Lesser General Public
1741- * License along with this library. If not, see
1742- * <http://www.gnu.org/licenses/>.
1743- *
1744- * Authored by Gordon Allott <gord.allott@canonical.com>
1745- */
1746-
1747-#ifndef _U_BUS_SERVER_H_
1748-#define _U_BUS_SERVER_H_
1749-
1750-#include <glib-object.h>
1751-#include <glib.h>
1752-G_BEGIN_DECLS
1753-
1754-#define UBUS_TYPE_SERVER (ubus_server_get_type ())
1755-#define UBUS_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UBUS_TYPE_SERVER, UBusServer))
1756-#define UBUS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UBUS_TYPE_SERVER, UBusServerClass))
1757-#define UBUS_IS_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UBUS_TYPE_SERVER))
1758-#define UBUS_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UBUS_TYPE_SERVER))
1759-#define UBUS_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UBUS_TYPE_SERVER, UBusServerClass))
1760-
1761-typedef struct _UBusServerClass UBusServerClass;
1762-typedef struct _UBusServer UBusServer;
1763-typedef struct _UBusServerPrivate UBusServerPrivate;
1764-
1765-struct _UBusServerClass
1766-{
1767- GObjectClass parent_class;
1768-
1769- /* padding */
1770- void (*_unity_padding1)(void);
1771- void (*_unity_padding2)(void);
1772- void (*_unity_padding3)(void);
1773- void (*_unity_padding4)(void);
1774- void (*_unity_padding5)(void);
1775- void (*_unity_padding6)(void);
1776-};
1777-
1778-struct _UBusServer
1779-{
1780- GObject parent_instance;
1781-
1782- UBusServerPrivate* priv;
1783-};
1784-
1785-typedef void (*UBusCallback)(GVariant* data,
1786- gpointer user_data);
1787-
1788-GType ubus_server_get_type(void) G_GNUC_CONST;
1789-UBusServer* ubus_server_get_default();
1790-void ubus_server_prime_context(UBusServer* server,
1791- GMainContext* context);
1792-guint ubus_server_register_interest(UBusServer* server,
1793- const gchar* message,
1794- UBusCallback callback,
1795- gpointer user_data);
1796-void ubus_server_send_message(UBusServer* server,
1797- const gchar* message,
1798- GVariant* data);
1799-void ubus_server_unregister_interest(UBusServer* server,
1800- guint handle);
1801-void ubus_server_force_message_pump(UBusServer* server);
1802-
1803-G_END_DECLS
1804-
1805-#endif /* _U_BUS_SERVER_H_ */