Merge lp:~robert-ancell/lightdm/liblightdm-better-sync into lp:lightdm

Proposed by Robert Ancell
Status: Merged
Merged at revision: 1972
Proposed branch: lp:~robert-ancell/lightdm/liblightdm-better-sync
Merge into: lp:lightdm
Diff against target: 452 lines (+235/-102)
1 file modified
liblightdm-gobject/greeter.c (+235/-102)
To merge this branch: bzr merge lp:~robert-ancell/lightdm/liblightdm-better-sync
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
LightDM Development Team Pending
Review via email: mp+217515@code.launchpad.net

Commit message

Handle unexpected messages during synchronous calls. This is taken from an unfinished asynchronous call branch.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'liblightdm-gobject/greeter.c'
2--- liblightdm-gobject/greeter.c 2014-02-25 03:53:40 +0000
3+++ liblightdm-gobject/greeter.c 2014-04-28 22:13:57 +0000
4@@ -54,6 +54,10 @@
5 gsize n_responses_waiting;
6 GList *responses_received;
7
8+ GList *connect_requests;
9+ GList *start_session_requests;
10+ GList *ensure_shared_data_dir_requests;
11+
12 GHashTable *hints;
13 guint autologin_timeout;
14
15@@ -95,6 +99,22 @@
16 SERVER_MESSAGE_SHARED_DIR_RESULT,
17 } ServerMessage;
18
19+/* Request sent to server */
20+typedef struct
21+{
22+ GObject parent_instance;
23+ gboolean complete;
24+ guint32 return_code;
25+ gchar *dir;
26+} Request;
27+typedef struct
28+{
29+ GObjectClass parent_class;
30+} RequestClass;
31+GType request_get_type (void);
32+#define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
33+G_DEFINE_TYPE (Request, request, G_TYPE_OBJECT);
34+
35 /**
36 * lightdm_greeter_new:
37 *
38@@ -108,6 +128,16 @@
39 return g_object_new (LIGHTDM_TYPE_GREETER, NULL);
40 }
41
42+static Request *
43+request_new (void)
44+{
45+ Request *request;
46+
47+ request = g_object_new (request_get_type (), NULL);
48+
49+ return request;
50+}
51+
52 static gboolean
53 timed_login_cb (gpointer data)
54 {
55@@ -251,6 +281,7 @@
56 gchar *version;
57 GString *hint_string;
58 int timeout;
59+ Request *request;
60
61 version = read_string (message, message_length, offset);
62 hint_string = g_string_new ("");
63@@ -264,6 +295,7 @@
64 g_string_append_printf (hint_string, " %s=%s", name, value);
65 }
66
67+ priv->connected = TRUE;
68 g_debug ("Connected version=%s%s", version, hint_string->str);
69 g_free (version);
70 g_string_free (hint_string, TRUE);
71@@ -275,6 +307,14 @@
72 g_debug ("Setting autologin timer for %d seconds", timeout);
73 priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
74 }
75+
76+ request = g_list_nth_data (priv->connect_requests, 0);
77+ if (request)
78+ {
79+ request->complete = TRUE;
80+ priv->connect_requests = g_list_remove (priv->connect_requests, request);
81+ g_object_unref (request);
82+ }
83 }
84
85 static void
86@@ -381,6 +421,75 @@
87 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
88 }
89
90+static void
91+handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
92+{
93+ LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
94+ Request *request;
95+
96+ request = g_list_nth_data (priv->start_session_requests, 0);
97+ if (request)
98+ {
99+ request->return_code = read_int (message, message_length, offset);
100+ request->complete = TRUE;
101+ priv->start_session_requests = g_list_remove (priv->start_session_requests, request);
102+ g_object_unref (request);
103+ }
104+}
105+
106+static void
107+handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
108+{
109+ LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
110+ Request *request;
111+
112+ request = g_list_nth_data (priv->ensure_shared_data_dir_requests, 0);
113+ if (request)
114+ {
115+ request->dir = read_string (message, message_length, offset);
116+ /* Blank data dir means invalid user */
117+ if (g_strcmp0 (request->dir, "") == 0)
118+ {
119+ g_free (request->dir);
120+ request->dir = NULL;
121+ }
122+ request->complete = TRUE;
123+ priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request);
124+ g_object_unref (request);
125+ }
126+}
127+
128+static void
129+handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
130+{
131+ gsize offset = 0;
132+ guint32 id;
133+
134+ id = read_int (message, message_length, &offset);
135+ read_int (message, message_length, &offset);
136+ switch (id)
137+ {
138+ case SERVER_MESSAGE_CONNECTED:
139+ handle_connected (greeter, message, message_length, &offset);
140+ break;
141+ case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
142+ handle_prompt_authentication (greeter, message, message_length, &offset);
143+ break;
144+ case SERVER_MESSAGE_END_AUTHENTICATION:
145+ handle_end_authentication (greeter, message, message_length, &offset);
146+ break;
147+ case SERVER_MESSAGE_SESSION_RESULT:
148+ handle_session_result (greeter, message, message_length, &offset);
149+ break;
150+ case SERVER_MESSAGE_SHARED_DIR_RESULT:
151+ handle_shared_dir_result (greeter, message, message_length, &offset);
152+ break;
153+ default:
154+ g_warning ("Unknown message from server: %d", id);
155+ break;
156+ }
157+}
158+
159 static guint8 *
160 read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
161 {
162@@ -442,33 +551,60 @@
163 {
164 LightDMGreeter *greeter = data;
165 guint8 *message;
166- gsize message_length, offset;
167- guint32 id;
168+ gsize message_length;
169
170+ /* Read one message and process it */
171 message = read_message (greeter, &message_length, FALSE);
172- if (!message)
173- return TRUE;
174-
175- offset = 0;
176- id = read_int (message, message_length, &offset);
177- read_int (message, message_length, &offset);
178- switch (id)
179+ if (message)
180 {
181- case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
182- handle_prompt_authentication (greeter, message, message_length, &offset);
183- break;
184- case SERVER_MESSAGE_END_AUTHENTICATION:
185- handle_end_authentication (greeter, message, message_length, &offset);
186- break;
187- default:
188- g_warning ("Unknown message from server: %d", id);
189- break;
190+ handle_message (greeter, message, message_length);
191+ g_free (message);
192 }
193- g_free (message);
194
195 return TRUE;
196 }
197
198+static void
199+send_connect (LightDMGreeter *greeter)
200+{
201+ guint8 message[MAX_MESSAGE_LENGTH];
202+ gsize offset = 0;
203+
204+ g_debug ("Connecting to display manager...");
205+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
206+ write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
207+ write_message (greeter, message, offset);
208+}
209+
210+static void
211+send_start_session (LightDMGreeter *greeter, const gchar *session)
212+{
213+ guint8 message[MAX_MESSAGE_LENGTH];
214+ gsize offset = 0;
215+
216+ if (session)
217+ g_debug ("Starting session %s", session);
218+ else
219+ g_debug ("Starting default session");
220+
221+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
222+ write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
223+ write_message (greeter, message, offset);
224+}
225+
226+static void
227+send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
228+{
229+ guint8 message[MAX_MESSAGE_LENGTH];
230+ gsize offset = 0;
231+
232+ g_debug ("Ensuring data directory for user %s", username);
233+
234+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
235+ write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
236+ write_message (greeter, message, offset);
237+}
238+
239 /**
240 * lightdm_greeter_connect_sync:
241 * @greeter: The greeter to connect
242@@ -483,10 +619,7 @@
243 {
244 LightDMGreeterPrivate *priv;
245 const gchar *fd;
246- guint8 message[MAX_MESSAGE_LENGTH];
247- guint8 *response;
248- gsize response_length, offset = 0;
249- guint32 id;
250+ Request *request;
251
252 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
253
254@@ -511,30 +644,25 @@
255 g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL);
256 g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
257
258- g_debug ("Connecting to display manager...");
259- write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION), &offset);
260- write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
261- write_message (greeter, message, offset);
262-
263- response = read_message (greeter, &response_length, TRUE);
264- if (!response)
265- return FALSE;
266-
267- offset = 0;
268- id = read_int (response, response_length, &offset);
269- read_int (response, response_length, &offset);
270- if (id == SERVER_MESSAGE_CONNECTED)
271- handle_connected (greeter, response, response_length, &offset);
272- g_free (response);
273- if (id != SERVER_MESSAGE_CONNECTED)
274+ /* Read until we are connected */
275+ send_connect (greeter);
276+ request = request_new ();
277+ priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
278+ do
279 {
280- g_warning ("Expected CONNECTED message, got %d", id);
281- return FALSE;
282- }
283-
284- priv->connected = TRUE;
285-
286- return TRUE;
287+ guint8 *message;
288+ gsize message_length;
289+
290+ message = read_message (greeter, &message_length, TRUE);
291+ if (!message)
292+ break;
293+ handle_message (greeter, message, message_length);
294+ g_free (message);
295+ } while (!request->complete);
296+
297+ g_object_unref (request);
298+
299+ return request->complete;
300 }
301
302 /**
303@@ -1070,10 +1198,8 @@
304 lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error)
305 {
306 LightDMGreeterPrivate *priv;
307- guint8 message[MAX_MESSAGE_LENGTH];
308- guint8 *response;
309- gsize response_length, offset = 0;
310- guint32 id, return_code = 1;
311+ Request *request;
312+ guint32 return_code;
313
314 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
315
316@@ -1082,28 +1208,24 @@
317 g_return_val_if_fail (priv->connected, FALSE);
318 g_return_val_if_fail (priv->is_authenticated, FALSE);
319
320- if (session)
321- g_debug ("Starting session %s", session);
322- else
323- g_debug ("Starting default session");
324-
325- write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
326- write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
327- write_message (greeter, message, offset);
328-
329- response = read_message (greeter, &response_length, TRUE);
330- if (!response)
331- return FALSE;
332-
333- offset = 0;
334- id = read_int (response, response_length, &offset);
335- read_int (response, response_length, &offset);
336- if (id == SERVER_MESSAGE_SESSION_RESULT)
337- return_code = read_int (response, response_length, &offset);
338- else
339- g_warning ("Expected SESSION_RESULT message, got %d", id);
340-
341- g_free (response);
342+ /* Read until the session is started */
343+ send_start_session (greeter, session);
344+ request = request_new ();
345+ priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request));
346+ do
347+ {
348+ guint8 *message;
349+ gsize message_length;
350+
351+ message = read_message (greeter, &message_length, TRUE);
352+ if (!message)
353+ break;
354+ handle_message (greeter, message, message_length);
355+ g_free (message);
356+ } while (!request->complete);
357+
358+ return_code = request->return_code;
359+ g_object_unref (request);
360
361 return return_code == 0;
362 }
363@@ -1130,11 +1252,8 @@
364 lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
365 {
366 LightDMGreeterPrivate *priv;
367- guint8 message[MAX_MESSAGE_LENGTH];
368- guint8 *response;
369- gsize response_length, offset = 0;
370- guint32 id;
371- gchar *data_dir = NULL;
372+ Request *request;
373+ gchar *data_dir;
374
375 g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
376
377@@ -1142,32 +1261,24 @@
378
379 g_return_val_if_fail (priv->connected, NULL);
380
381- g_debug ("Ensuring data directory for user %s", username);
382-
383- write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
384- write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
385- write_message (greeter, message, offset);
386-
387- response = read_message (greeter, &response_length, TRUE);
388- if (!response)
389- return NULL;
390-
391- offset = 0;
392- id = read_int (response, response_length, &offset);
393- read_int (response, response_length, &offset);
394- if (id == SERVER_MESSAGE_SHARED_DIR_RESULT)
395- data_dir = read_string (response, response_length, &offset);
396- else
397- g_warning ("Expected SHARED_DIR_RESULT message, got %d", id);
398-
399- /* Blank data dir means invalid user */
400- if (g_strcmp0 (data_dir, "") == 0)
401+ /* Read until a response */
402+ send_ensure_shared_data_dir (greeter, username);
403+ request = request_new ();
404+ priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request));
405+ do
406 {
407- g_free (data_dir);
408- data_dir = NULL;
409- }
410-
411- g_free (response);
412+ guint8 *message;
413+ gsize message_length;
414+
415+ message = read_message (greeter, &message_length, TRUE);
416+ if (!message)
417+ break;
418+ handle_message (greeter, message, message_length);
419+ g_free (message);
420+ } while (!request->complete);
421+
422+ data_dir = g_strdup (request->dir);
423+ g_object_unref (request);
424
425 return data_dir;
426 }
427@@ -1461,3 +1572,25 @@
428 NULL,
429 G_TYPE_NONE, 0);
430 }
431+
432+static void
433+request_init (Request *request)
434+{
435+}
436+
437+static void
438+request_finalize (GObject *object)
439+{
440+ Request *request = REQUEST (object);
441+
442+ g_free (request->dir);
443+
444+ G_OBJECT_CLASS (request_parent_class)->finalize (object);
445+}
446+
447+static void
448+request_class_init (RequestClass *klass)
449+{
450+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
451+ object_class->finalize = request_finalize;
452+}

Subscribers

People subscribed via source and target branches