Merge lp:~bregma/geis/lp-921633 into lp:geis

Proposed by Stephen M. Webb
Status: Merged
Approved by: Daniel d'Andrada
Approved revision: 206
Merged at revision: 207
Proposed branch: lp:~bregma/geis/lp-921633
Merge into: lp:geis
Diff against target: 318 lines (+99/-51)
6 files modified
include/geis/geis.h (+5/-0)
libutouch-geis/geis.c (+88/-0)
libutouch-geis/geis_v1.c (+2/-50)
python/_geis_bindings/_geis_bindings.c (+1/-0)
python/geis/__init__.py (+1/-0)
python/pygeis (+2/-1)
To merge this branch: bzr merge lp:~bregma/geis/lp-921633
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) Approve
Review via email: mp+94010@code.launchpad.net

Description of the change

Adds an init flag to geis_new() to enable blocking startup. Using the GEIS_INIT_SYNCHRONOUS_START flag will cause geis_new() to block until either initialization is complete, initialization has failed, or 5 seconds has elapsed, whichever comes first. Without the new init flag, geis_new() completes asynchronously as before.

The GEISv1 interface was modified to use this init flag instead of performing its own internal wait loop. Running the geistest tool exercises the new functionality, running the geisview tool exercises the older functionality.

This change closes lp:921633.

To post a comment you must log in.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

    #define GEIS_INIT_SYNCHRONOUS_START "org.libgeis.init.synchronous.start"

To keep consistency with the other org.libgeis.init.*, maybe it should be "org.libgeis.init.synchronous-start" instead (s/.start/-start).

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In ibutouch-geis/geis.c
 742 | static void
 743 | _geis_destroy(Geis geis)

Unrelated cosmetic change.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In libutouch-geis/geis_v1.c:

534 -- instance->geis = geis_new(GEIS_INIT_TRACK_DEVICES,
535 -- GEIS_INIT_TRACK_GESTURE_CLASSES,
536 -- NULL);
491 ++ instance->geis = geis_new(GEIS_INIT_SYNCHRONOUS_START, NULL);

I think GEIS_INIT_TRACK_DEVICES and GEIS_INIT_TRACK_GESTURE_CLASSES should be kept there since their removal doesn't seem related with the objective of this patch. Same for the pygeis change.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Other than those small details it looks good.

review: Approve
lp:~bregma/geis/lp-921633 updated
207. By Stephen M. Webb

integrated suggested changes from review

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/geis/geis.h'
2--- include/geis/geis.h 2012-02-22 18:41:32 +0000
3+++ include/geis/geis.h 2012-02-23 19:46:19 +0000
4@@ -459,11 +459,16 @@
5 * @def GEIS_INIT_TRACK_GESTURE_CLASSES
6 * Tells GEIS to send gesture class events.
7 * This initialization argument takes no parameters.
8+ *
9+ * @def GEIS_INIT_SYNCHRONOUS_START
10+ * Performs all setup synchronously: geis_new() will block until all setup has
11+ * completed successfully or unsuccessfully.
12 */
13
14 #define GEIS_INIT_SERVICE_PROVIDER "org.libgeis.init.server"
15 #define GEIS_INIT_TRACK_DEVICES "org.libgeis.init.track-devices"
16 #define GEIS_INIT_TRACK_GESTURE_CLASSES "org.libgeis.init.track-gesture-classes"
17+#define GEIS_INIT_SYNCHRONOUS_START "org.libgeis.init.synchronous-start"
18
19 /* @} */
20
21
22=== modified file 'libutouch-geis/geis.c'
23--- libutouch-geis/geis.c 2012-02-12 04:45:01 +0000
24+++ libutouch-geis/geis.c 2012-02-23 19:46:19 +0000
25@@ -42,9 +42,30 @@
26 #include "geis_logging.h"
27 #include <stdarg.h>
28 #include <string.h>
29+#include <sys/select.h>
30 #include <unistd.h>
31
32
33+/** Default timeout for synchronous init (in seconds */
34+#define GEIS_DEFAULT_INIT_TIMEOUT 5
35+
36+/**
37+ * States the GEIS instance could be in.
38+ *
39+ * @def GEIS_STATE_INITIALIZING
40+ * The instance has not yet completed its initialization sequence: some
41+ * functions will not yield valid results.
42+ *
43+ * @def GEIS_STATE_RUNNING
44+ * Initialization has completed, the instance is up and running normally.
45+ */
46+typedef enum _GeisState
47+{
48+ GEIS_STATE_INITIALIZING,
49+ GEIS_STATE_RUNNING
50+} _GeisState;
51+
52+
53 /*
54 * An internal structure to track processing callbacks in some order.
55 */
56@@ -65,6 +86,7 @@
57 struct _Geis
58 {
59 GeisRefCount refcount;
60+ _GeisState state;
61 GeisErrorStack error_stack;
62 GeisSubBag subscription_bag;
63 GeisBackendMultiplexor backend_multiplexor;
64@@ -89,6 +111,7 @@
65 FilterableAttributeBag region_filterable_attributes;
66 FilterableAttributeBag special_filterable_attributes;
67 GeisGestureFlick flick;
68+ GeisBoolean use_synchronous_start;
69 GeisBoolean use_atomic_gestures;
70 GeisBoolean send_tentative_events;
71 GeisBoolean send_synchronous_events;
72@@ -234,6 +257,7 @@
73 break;
74
75 case GEIS_EVENT_INIT_COMPLETE:
76+ geis->state = GEIS_STATE_RUNNING;
77 geis->backend_pending = GEIS_FALSE;
78 break;
79
80@@ -375,6 +399,8 @@
81 goto final_exit;
82 }
83
84+ geis->state = GEIS_STATE_INITIALIZING;
85+
86 geis->subscription_bag = geis_subscription_bag_new(1);
87 if (!geis->subscription_bag)
88 {
89@@ -468,6 +494,7 @@
90 goto unwind_region_attrs;
91 }
92
93+ geis->use_synchronous_start = GEIS_FALSE;
94 geis->use_atomic_gestures = GEIS_TRUE;
95 geis->send_tentative_events = GEIS_FALSE;
96 geis->send_synchronous_events = GEIS_FALSE;
97@@ -535,6 +562,10 @@
98 {
99 /* no longer supported */
100 }
101+ else if (0 == strcmp(init_arg_name, GEIS_INIT_SYNCHRONOUS_START))
102+ {
103+ geis->use_synchronous_start = GEIS_TRUE;
104+ }
105 else if (0 == strcmp(init_arg_name, GEIS_INIT_NO_ATOMIC_GESTURES))
106 {
107 geis->use_atomic_gestures = GEIS_FALSE;
108@@ -619,6 +650,51 @@
109
110
111 /**
112+ * Performs a blocking wait for a GEIS_INIT message.
113+ */
114+static GeisStatus
115+_geis_wait_for_init(Geis geis)
116+{
117+ geis_debug("waiting for initialization to complete...");
118+ GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
119+ int geis_fd = geis_backend_multiplexor_fd(geis->backend_multiplexor);
120+
121+ while (1)
122+ {
123+ fd_set read_fds;
124+ FD_ZERO(&read_fds);
125+ FD_SET(geis_fd, &read_fds);
126+ struct timeval timeout = { GEIS_DEFAULT_INIT_TIMEOUT, 0 };
127+
128+ int sstat = select(geis_fd + 1, &read_fds, NULL, NULL, &timeout);
129+ if (sstat < 0)
130+ {
131+ geis_error("error %d in select(): %s", errno, strerror(errno));
132+ break;
133+ }
134+ else if (sstat == 0)
135+ {
136+ geis_error("failed to get init response");
137+ break;
138+ }
139+
140+ if (FD_ISSET(geis_fd, &read_fds))
141+ {
142+ status = geis_dispatch_events(geis);
143+ if (geis->state == GEIS_STATE_RUNNING)
144+ {
145+ status = GEIS_STATUS_SUCCESS;
146+ break;
147+ }
148+ }
149+ }
150+
151+ geis_debug("... initialization complete, status=%d", status);
152+ return status;
153+}
154+
155+
156+/**
157 * Creates an initialized Geis API instance.
158 */
159 Geis
160@@ -644,6 +720,18 @@
161 geis = NULL;
162 goto final_exit;
163 }
164+
165+ if (geis->use_synchronous_start)
166+ {
167+ GeisStatus status = _geis_wait_for_init(geis);
168+ if (status != GEIS_STATUS_SUCCESS)
169+ {
170+ geis_delete(geis);
171+ geis = NULL;
172+ goto final_exit;
173+ }
174+ }
175+
176 geis->flick = geis_gesture_flick_new(geis);
177
178 final_exit:
179
180=== modified file 'libutouch-geis/geis_v1.c'
181--- libutouch-geis/geis_v1.c 2012-02-15 20:31:36 +0000
182+++ libutouch-geis/geis_v1.c 2012-02-23 19:46:19 +0000
183@@ -42,7 +42,6 @@
184 GeisPointer input_context;
185 GeisGestureFuncs gesture_funcs;
186 GeisPointer gesture_cookie;
187- GeisBoolean has_init;
188 GeisBoolean init_failed;
189 };
190
191@@ -336,13 +335,11 @@
192 switch (geis_event_type(event))
193 {
194 case GEIS_EVENT_INIT_COMPLETE:
195- geis_debug("received INIT_COMPLETE");
196- v1_instance->has_init = GEIS_TRUE;
197+ geis_debug("received INIT event");
198 goto final_exit;
199
200 case GEIS_EVENT_ERROR:
201 geis_debug("received ERROR event");
202- v1_instance->has_init = GEIS_TRUE;
203 v1_instance->init_failed = GEIS_TRUE;
204 goto final_exit;
205
206@@ -460,46 +457,6 @@
207 }
208
209
210-static void
211-_geis_v1_wait_for_init(GeisInstance geis_instance)
212-{
213- int geis_fd = -1;
214- GeisStatus status = geis_get_configuration(geis_instance->geis,
215- GEIS_CONFIGURATION_FD,
216- &geis_fd);
217- if (status == GEIS_STATUS_SUCCESS)
218- {
219- while (1)
220- {
221- fd_set read_fds;
222- FD_ZERO(&read_fds);
223- FD_SET(geis_fd, &read_fds);
224- struct timeval timeout = { 5, 0 }; /* wait up to 5 seconds */
225-
226- int sstat = select(geis_fd + 1, &read_fds, NULL, NULL, &timeout);
227- if (sstat < 0)
228- {
229- geis_error("error %d in select(): %s", errno, strerror(errno));
230- break;
231- }
232- else if (sstat == 0)
233- {
234- geis_error("failed to get init response");
235- geis_instance->init_failed = GEIS_TRUE;
236- break;
237- }
238-
239- if (FD_ISSET(geis_fd, &read_fds))
240- {
241- status = geis_dispatch_events(geis_instance->geis);
242- if (geis_instance->has_init)
243- break;
244- }
245- }
246- }
247-}
248-
249-
250 GeisStatus
251 geis_init(GeisWinInfo* win_info, GeisInstance *geis_instance)
252 {
253@@ -533,6 +490,7 @@
254 {
255 instance->geis = geis_new(GEIS_INIT_TRACK_DEVICES,
256 GEIS_INIT_TRACK_GESTURE_CLASSES,
257+ GEIS_INIT_SYNCHRONOUS_START,
258 NULL);
259 }
260 if (!instance->geis)
261@@ -541,11 +499,6 @@
262 }
263
264 geis_register_event_callback(instance->geis, _v1_event_callback, instance);
265- _geis_v1_wait_for_init(instance);
266- if (instance->init_failed)
267- {
268- goto unwind_instance;
269- }
270
271 instance->subscription = geis_subscription_new(instance->geis,
272 _generate_subscription_name(xcb_win_info),
273@@ -558,7 +511,6 @@
274 status = geis_subscription_add_filter(instance->subscription,
275 instance->window_filter);
276
277- instance->has_init = GEIS_FALSE;
278 instance->init_failed = GEIS_FALSE;
279
280 *geis_instance = instance;
281
282=== modified file 'python/_geis_bindings/_geis_bindings.c'
283--- python/_geis_bindings/_geis_bindings.c 2011-11-21 21:32:47 +0000
284+++ python/_geis_bindings/_geis_bindings.c 2012-02-23 19:46:19 +0000
285@@ -53,6 +53,7 @@
286 PyModule_AddStringMacro(this_module, GEIS_INIT_SERVICE_PROVIDER);
287 PyModule_AddStringMacro(this_module, GEIS_INIT_TRACK_DEVICES);
288 PyModule_AddStringMacro(this_module, GEIS_INIT_TRACK_GESTURE_CLASSES);
289+ PyModule_AddStringMacro(this_module, GEIS_INIT_SYNCHRONOUS_START);
290 PyModule_AddStringMacro(this_module, GEIS_INIT_UTOUCH_MOCK_BACKEND);
291 PyModule_AddStringMacro(this_module, GEIS_INIT_UTOUCH_DBUS_BACKEND);
292 PyModule_AddStringMacro(this_module, GEIS_INIT_UTOUCH_GRAIL_BACKEND);
293
294=== modified file 'python/geis/__init__.py'
295--- python/geis/__init__.py 2011-12-19 22:15:23 +0000
296+++ python/geis/__init__.py 2012-02-23 19:46:19 +0000
297@@ -34,6 +34,7 @@
298 'GEIS_INIT_SERVICE_PROVIDER',
299 'GEIS_INIT_TRACK_DEVICES',
300 'GEIS_INIT_TRACK_GESTURE_CLASSES',
301+ 'GEIS_INIT_SYNCHRONOUS_START',
302 'GEIS_INIT_UTOUCH_MOCK_BACKEND',
303 'GEIS_INIT_UTOUCH_DBUS_BACKEND',
304 'GEIS_INIT_UTOUCH_GRAIL_BACKEND',
305
306=== modified file 'python/pygeis'
307--- python/pygeis 2011-05-27 12:50:51 +0000
308+++ python/pygeis 2012-02-23 19:46:19 +0000
309@@ -119,7 +119,8 @@
310 sys.exit(1)
311
312 g = geis.Geis(geis.GEIS_INIT_TRACK_DEVICES,
313- geis.GEIS_INIT_TRACK_GESTURE_CLASSES)
314+ geis.GEIS_INIT_TRACK_GESTURE_CLASSES,
315+ geis.GEIS_INIT_SYNCHRONOUS_START)
316 geis_fd = g.get_configuration(geis.GEIS_CONFIGURATION_FD)
317 sub = geis.Subscription(g)
318 g.register_class_callback(_class_callback, sub)

Subscribers

People subscribed via source and target branches