nautilus/libnautilus/nautilus-idle-queue.c
Darin Adler 4536e0f5b3 reviewed by: John Sullivan <sullivan@eazel.com>
Fix another part of bug 7494 (History sidebar component spews
	assertions when closing nautilus window [and sometimes crashes]):

	* libnautilus/nautilus-idle-queue.c: (execute_queued_functions):
	Change logic so that queued functions no longer execute once the
	caller destroys the queue.

	Fix bug 7564 (opening and quickly closing window in list view
	leads to core dump):

	* src/file-manager/fm-directory-view.c:
	(fm_directory_view_destroy): Remove code to empty lists now that
	stop handles that.
	(load_error_callback): Added a FIXME about the fact that we throw
	away some pending files on an error.
	(fm_directory_view_stop): Don't display pending files any more.
	This is a problem when trying to destroy, and also the old code
	displayed only one "batch" of pending files, so it wasn't really
	making sure all the files were displayed anyway. If we re-add the
	code to display pending files here, we'll have to make sure it
	doesn't do this for the destroy case.
	* src/file-manager/fm-list-view.c: Added FIXME asking why the "add
	100 items at a time" logic is only needed for list view, and not
	for icon view. If both kinds of views had it, it could be done
	more simply at the FMDirectoryView level.

	* libnautilus-extensions/nautilus-icon-factory.c:
	(nautilus_get_icon_size_for_zoom_level): Fix this code so that it
	doesn't do a core dump if it gets a bad size. This is not the
	cause of the problem, but it's good to fix this too, because a
	core dump is overreacting to a bad parameter.
2001-03-08 19:53:30 +00:00

140 lines
3.2 KiB
C

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */
/*
* libnautilus: A library for nautilus view implementations.
*
* Copyright (C) 2001 Eazel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Author: Darin Adler <darin@eazel.com>
*
*/
#include <config.h>
#include "nautilus-idle-queue.h"
#include <gtk/gtkmain.h>
struct NautilusIdleQueue {
GList *functions;
guint idle_id;
gboolean in_idle;
gboolean destroy;
};
typedef struct {
GFunc callback;
gpointer data;
gpointer callback_data;
GFreeFunc free_callback_data;
} QueuedFunction;
static gboolean
execute_queued_functions (gpointer callback_data)
{
NautilusIdleQueue *queue;
GList *functions, *node;
QueuedFunction *function;
queue = callback_data;
/* We could receive more incoming functions while dispatching
* these, so keep going until the queue is empty.
*/
queue->in_idle = TRUE;
while (queue->functions != NULL) {
functions = g_list_reverse (queue->functions);
queue->functions = NULL;
for (node = functions; node != NULL; node = node->next) {
function = node->data;
if (!queue->destroy) {
(* function->callback) (function->data, function->callback_data);
}
if (function->free_callback_data != NULL) {
(* function->free_callback_data) (function->callback_data);
}
}
g_list_free (functions);
}
queue->in_idle = FALSE;
queue->idle_id = 0;
if (queue->destroy) {
nautilus_idle_queue_destroy (queue);
}
return FALSE;
}
NautilusIdleQueue *
nautilus_idle_queue_new (void)
{
return g_new0 (NautilusIdleQueue, 1);
}
void
nautilus_idle_queue_add (NautilusIdleQueue *queue,
GFunc callback,
gpointer data,
gpointer callback_data,
GFreeFunc free_callback_data)
{
QueuedFunction *function;
function = g_new (QueuedFunction, 1);
function->callback = callback;
function->data = data;
function->callback_data = callback_data;
function->free_callback_data = free_callback_data;
queue->functions = g_list_prepend (queue->functions, function);
if (queue->idle_id == 0) {
queue->idle_id = gtk_idle_add (execute_queued_functions, queue);
}
}
void
nautilus_idle_queue_destroy (NautilusIdleQueue *queue)
{
GList *node;
QueuedFunction *function;
if (queue->in_idle) {
queue->destroy = TRUE;
return;
}
for (node = queue->functions; node != NULL; node = node->next) {
function = node->data;
if (function->free_callback_data != NULL) {
(* function->free_callback_data) (function->callback_data);
}
}
g_list_free (queue->functions);
if (queue->idle_id != 0) {
gtk_idle_remove (queue->idle_id);
}
g_free (queue);
}