[Patch] Fix for #96915, #105290



Hello,

here's a patch that fixes nautilus crashing on startup when it is
shutdown immediately (like with -q, --no-default-window &&
show_desktop=off).

gnome_vfs_async_job_map_get_job doesn't handle the case that there's no
job map yet/anymore gracefully. All of its callers assume it returns
NULL if you try to remove a non-existing job. But it asserts the job_map
is not null and bails out via g_assert() otherwise. But a non_existing
job_map is just a special case of a non-existing job in it.

If Nautilus is immediately shutdown after startup remove_trash_volume()
in nautilus-trash-volume tries to cancel the
gnome_vfs_async_find_directory jobs it fired up. But at that point the
jobs are already finished and the map destroyed - leading to the
assertion failure. This cancellation takes only place if the handle is
not null. This handle is set to null in the callback that is called when
an operation is finished, so no cancel should be executed for a finished
operation. That works fine most of time, but if a shutdown is in
progress it doesn't. The callbacks to be called after the job are
registered with g_idle_add() and executed when there's nothing more
important to do. Well, as it turns out, during shutdown of Nautilus
there's always more important stuff to do until the application exits
and the main loop is destroyed. So the callbacks are never called,
handle never set to null and cancel called on all trash volume jobs at a
time where there's no job_map anymore. That's bug #96915, which I can
reproduce by setting show_desktop=off and starting nautilus with
nautilus --no-default-window (as gnome-session does).

Another way to fix this would be to register the callbacks in a way that
execution is guarantied in a timely manner for the finish callbacks of
the async operations and make the trash code work as intendend.
Actually, the whole of nautilus-directory-async.c uses the same
mechanism of flags which get nullified in the callbacks (see the stack
of #105290).

But in any case job_map_get_job should not crap out when there's no job
map.

Sorry for the long winded explanation,

Martin

Index: gnome-vfs-async-job-map.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-async-job-map.c,v
retrieving revision 1.12
diff -u -r1.12 gnome-vfs-async-job-map.c
--- gnome-vfs-async-job-map.c   19 Dec 2002 17:57:19 -0000      1.12
+++ gnome-vfs-async-job-map.c   17 Sep 2003 00:47:46 -0000
@@ -50,7 +50,10 @@
 _gnome_vfs_async_job_map_get_job (const GnomeVFSAsyncHandle *handle)
 {
        _gnome_vfs_async_job_map_assert_locked ();
-       g_assert (async_job_map != NULL);
+
+    if (async_job_map == NULL) {
+        return NULL;
+    }
  
        return g_hash_table_lookup (async_job_map, handle);
 }





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]