Merge lp:~mhr3/unity/ubus-rewrite into lp:unity
- ubus-rewrite
- Merge into trunk
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 |
Related bugs: |
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).
Brandon Schaefer (brandontschaefer) wrote : | # |
Andrea Azzarone (azzar1) wrote : | # |
966 +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_
990 + return;
991 + }
992 + }
Can you use the range-based for loop of std::erase + std::remove_if?
995 +void UBusServer:
996 + glib::Variant const& args)
997 +{
998 + SendMessageFull
999 +}
1000 +
1001 +void UBusServer:
1002 + glib::Variant const& args,
1003 + glib::Source:
1004 +{
What about default value here?
+ msg_queue_
ouch :) std::make_pair will make this line shorter :)
1009 + auto src_nick = boost::
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(
1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
1224 + {
1225 + UnregisterInter
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(
for (...) {
auto to_delete = it;
it++; // don't do this above too :)
UnregisterInt
}
But i'm not really sure about this :)
1274 +#include <map>
Should not be necessary.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
1006 + msg_queue_
It can be just std::make_
1009 + auto src_nick = boost::
No need for it with C++11, just use std::to_
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:
I know this is safer, but what's the reason why not to add also UBusServer:
[NVM, I've noticed that now there's only just one static UBusServer: +1].
1034 + for (unsigned i = 0; i < dispatched_
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(
1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
1224 + {
1225 + UnregisterInter
1226 + }
this is also safe:
for (auto it = ids_copy.begin(); it != ids_copy.end();)
{
UnregisterInt
}
1317 + static std::unique_
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:
PS: add yourself to to authors, so people will bother you when on troubles ;-D
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(
> ...
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.
Michal Hruby (mhr3) wrote : | # |
> 1034 + for (unsigned i = 0; i < dispatched_
>
> 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(
> 1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
> 1224 + {
> 1225 + UnregisterInter
> 1226 + }
>
> this is also safe:
> for (auto it = ids_copy.begin(); it != ids_copy.end();)
> {
> UnregisterInter
> }
True, but it looks weird :P
>
> 1317 + static std::unique_
>
> 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:
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.
Andrea Azzarone (azzar1) wrote : | # |
> 966 +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_
> 990 + return;
> 991 + }
> 992 + }
>
> Can you use the range-based for loop of std::erase + std::remove_if?
>
> 995 +void UBusServer:
> 996 + glib::Variant const& args)
> 997 +{
> 998 + SendMessageFull
> glib::Source:
> 999 +}
> 1000 +
> 1001 +void UBusServer:
> 1002 + glib::Variant const& args,
> 1003 + glib::Source:
> 1004 +{
I mean you ca do:
class UbusServer {
...
void SendMessage(
...
}
So you don't need two functions. But this is not blocking.
>
> What about default value here?
>
> + msg_queue_
> glib::Variant>
> args)));
>
> ouch :) std::make_pair will make this line shorter :)
>
> 1009 + auto src_nick =
> boost::
>
> 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(
> 1223 + for (auto it = ids_copy.begin(); it != ids_copy.end(); ++it)
> 1224 + {
> 1225 + UnregisterInter
> 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(
>
> for (...) {
> auto to_delete = it;
> it++; // don't do this above too :)
> UnregisterInter
> }
>
> But i'm not really sure about this :)
>
> 1274 +#include <map>
>
> Should not be necessary.
Michal Hruby (mhr3) wrote : | # |
> void SendMessage(
> args, glib::Source:
> ...
> }
>
> 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.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Looks nice now, thanks
Preview Diff
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_ */ |
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!