Index: libeog/eog-image-private.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image-private.h,v
retrieving revision 1.16
diff -u -r1.16 eog-image-private.h
--- libeog/eog-image-private.h	4 Mar 2006 01:50:51 -0000	1.16
+++ libeog/eog-image-private.h	17 Jul 2006 15:46:39 -0000
@@ -50,6 +50,7 @@
 	gchar *caption_key;
 
 	GThread *load_thread;
+	GMutex *mutex;
 	GMutex *status_mutex;
 	GCond  *load_finished;
 	gboolean cancel_loading;
Index: libeog/eog-image.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image.c,v
retrieving revision 1.69
diff -u -r1.69 eog-image.c
--- libeog/eog-image.c	1 Jun 2006 04:03:01 -0000	1.69
+++ libeog/eog-image.c	17 Jul 2006 15:46:39 -0000
@@ -106,6 +106,11 @@
 		g_free (priv->error_message);
 		priv->error_message = NULL;
 	}
+
+	if (priv->mutex) {
+		g_mutex_free (priv->mutex);
+		priv->mutex = NULL;
+	}
 	
 	if (priv->status_mutex) {
 		g_mutex_free (priv->status_mutex);
@@ -257,6 +262,7 @@
 	priv->thumbnail = NULL;
 	priv->width = priv->height = -1;
 	priv->modified = FALSE;
+	priv->mutex = g_mutex_new ();
 	priv->status_mutex = g_mutex_new ();
 	priv->load_finished = NULL;
 	priv->error_message = NULL;
@@ -271,6 +277,24 @@
 	img->priv = priv;
 }
 
+void eog_image_lock (EogImage *image)
+{
+        g_return_if_fail (EOG_IS_IMAGE (image));
+	g_return_if_fail (image->priv != NULL);
+	g_return_if_fail (image->priv->mutex != NULL);
+
+	g_mutex_lock (image->priv->mutex);
+}
+
+void eog_image_unlock (EogImage *image)
+{
+        g_return_if_fail (EOG_IS_IMAGE (image));
+	g_return_if_fail (image->priv != NULL);
+	g_return_if_fail (image->priv->mutex != NULL);
+
+	g_mutex_unlock (image->priv->mutex);
+}
+
 EogImage* 
 eog_image_new_uri (GnomeVFSURI *uri)
 {
@@ -1692,6 +1716,7 @@
 	g_mutex_lock (priv->status_mutex);
 	if (priv->status == EOG_IMAGE_STATUS_LOADING) {
 		priv->cancel_loading = TRUE;
+		priv->status = EOG_IMAGE_STATUS_UNKNOWN;
 	}
 	g_mutex_unlock (priv->status_mutex);
 }
Index: libeog/eog-image.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image.h,v
retrieving revision 1.27
diff -u -r1.27 eog-image.h
--- libeog/eog-image.h	4 Mar 2006 01:50:51 -0000	1.27
+++ libeog/eog-image.h	17 Jul 2006 15:46:39 -0000
@@ -76,6 +76,8 @@
 
 /* loading API */
 EogImage*           eog_image_new                            (const char *txt_uri);
+void                eog_image_lock (EogImage *image);
+void                eog_image_unlock (EogImage *image);
 EogImage*           eog_image_new_uri                        (GnomeVFSURI *uri);
 gboolean            eog_image_load                           (EogImage *img, 
 							      guint data2read, 
Index: libeog/eog-job-manager.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-job-manager.c,v
retrieving revision 1.7
diff -u -r1.7 eog-job-manager.c
--- libeog/eog-job-manager.c	19 Feb 2006 03:21:22 -0000	1.7
+++ libeog/eog-job-manager.c	17 Jul 2006 15:46:40 -0000
@@ -86,11 +86,6 @@
 				
 				g_assert (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED ||
 					  eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED);
-			}
-			
-			if (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED ||
-			    eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED)
-			{
 				g_idle_add (job_finished_cb, job);
 			}
 		}
Index: libeog/eog-job.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-job.c,v
retrieving revision 1.6
diff -u -r1.6 eog-job.c
--- libeog/eog-job.c	19 Feb 2006 03:21:22 -0000	1.6
+++ libeog/eog-job.c	17 Jul 2006 15:46:40 -0000
@@ -376,6 +376,7 @@
 		job->priv->progress_last_called = 0.0;
 		job->priv->progress_nth_part = 0;
 	}
+
 	g_mutex_unlock (job->priv->mutex);
 
 	if (!do_action) {
Index: shell/eog-window.c
===================================================================
RCS file: /cvs/gnome/eog/shell/eog-window.c,v
retrieving revision 1.194
diff -u -r1.194 eog-window.c
--- shell/eog-window.c	26 Jun 2006 07:42:23 -0000	1.194
+++ shell/eog-window.c	17 Jul 2006 15:46:40 -0000
@@ -108,6 +108,9 @@
 	EogImageList        *image_list;
 	EogImage            *displayed_image;
 
+        /* The next image to display. */
+        EogImage            *next_image;
+
 	/* ui/widget stuff */
 	GtkUIManager        *ui_mgr;
 	GtkWidget           *box;
@@ -2535,6 +2538,7 @@
 
 	priv->image_list = NULL;
 	priv->displayed_image = NULL;
+	priv->next_image = NULL;
 	priv->sig_id_list_prepared = 0;
 
 	g_object_set (G_OBJECT (window), "allow_shrink", TRUE, NULL);
@@ -3131,13 +3135,35 @@
 job_image_load_action (EogJob *job, gpointer data, GError **error)
 {
 	EogJobImageLoadData *job_data;
+	EogWindow *window;
+	EogImage *image;
 
 	job_data = (EogJobImageLoadData*) data;
+	window = EOG_JOB_DATA (job_data)->window;
+	image = job_data->image;
 
-	eog_image_load (EOG_IMAGE (job_data->image),
-			EOG_IMAGE_DATA_ALL,
-			job,
-			error);
+	/* The companion unlock is in job_image_load_finished. This doesn't
+	 * dead-lock because both functions are called sequentially by the 
+	 * same thread. This seems too much like a miracle for my tastes. */
+	eog_image_lock (image);
+
+	/* Check to see if the job is still relevant. */
+	if (window->priv->next_image != image) {
+        	  eog_image_unlock (image);
+	          return;
+	}
+
+	if (!eog_image_is_loaded (image)) {	  
+	        eog_image_load (EOG_IMAGE (job_data->image),
+				EOG_IMAGE_DATA_ALL,
+				job,
+				error);
+	} else {
+	        /* We still want to display the image with the finished
+		 * handler so we keep an extra ref to it to make sure it 
+		 * isn't released early. */
+	        g_object_ref (image);
+	}
 }
 
 static void
@@ -3151,6 +3177,22 @@
 	window = EOG_JOB_DATA (job_data)->window;
 	image = job_data->image;
 
+	/* Check to see if the job is still relevant. */
+	if (window->priv->next_image != image) {
+        	  eog_image_unlock (image);
+	          return;
+	}
+
+	/* This is a hack to get around a very rare race condition
+	 * where the first half of the job has decided that the
+	 * image has data and doesn't need to be reloaded, but the
+	 * image data has gone AWOL by this point. This does not
+	 * fix the cause, but I'm damned if I can find it. */
+	if (!eog_image_has_data (image, EOG_IMAGE_DATA_ALL)) {
+	        eog_image_unlock (image);
+		return;
+	}
+
 	if (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED) {
 		if (eog_job_get_success (job)) { 
 			/* successfull */
@@ -3178,6 +3220,9 @@
 	}
 
 	g_object_unref (image);
+
+	/* The companion lock is in job_image_load_action. */
+	eog_image_unlock (image);
 }
 
 static void
@@ -3251,9 +3296,10 @@
 	EOG_JOB_DATA (data)->window = window;
 	data->image = image; /* no additional ref required, since 
 			      * its already increased by 
-			      * eog_wrap_lsit_get_first_selected_image
-			      */
-	
+			      * eog_wrap_list_get_first_selected_image
+			      */	
+	window->priv->next_image = image;
+
 	job = eog_job_new_full (data,
 				job_image_load_action,
 				job_image_load_finished,
