summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog78
-rwxr-xr-xcheck-FIXME.pl2
-rw-r--r--libnautilus-extensions/nautilus-directory-async.c372
-rw-r--r--libnautilus-extensions/nautilus-directory-private.h1
-rw-r--r--libnautilus-extensions/nautilus-directory.c2
-rw-r--r--libnautilus-extensions/nautilus-file-private.h9
-rw-r--r--libnautilus-extensions/nautilus-file.c111
-rw-r--r--libnautilus-private/nautilus-directory-async.c372
-rw-r--r--libnautilus-private/nautilus-directory-private.h1
-rw-r--r--libnautilus-private/nautilus-directory.c2
-rw-r--r--libnautilus-private/nautilus-file-private.h9
-rw-r--r--libnautilus-private/nautilus-file.c111
-rw-r--r--src/file-manager/fm-directory-view.c8
-rw-r--r--user-guide/C/Makefile.am1
14 files changed, 706 insertions, 373 deletions
diff --git a/ChangeLog b/ChangeLog
index 17c990c65..f0ae566f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,80 @@
+2000-10-17 Darin Adler <darin@eazel.com>
+
+ * check-FIXME.pl: Skip the macros directory.
+
+ * libnautilus-extensions/nautilus-directory-async.c:
+ (async_job_start), (async_job_end), (get_one_value_callback),
+ (get_one_value), (async_job_wake_up): Add new calls that limit the
+ number of async. jobs done at once.
+ (directory_count_cancel), (deep_count_cancel), (mime_list_cancel),
+ (top_left_cancel), (activation_uri_cancel), (file_info_cancel),
+ (metafile_read_cancel), (metafile_read_done): End the async. job
+ if it's cancelled.
+ (metafile_read_try_public_metafile), (metafile_read_restart):
+ Changed the old metafile_read_start function's name to
+ metafile_read_restart since it's used on the second try.
+ (is_anyone_waiting_for_metafile), (metafile_read_start): Move the
+ logic about whether to start reading into this function to make it
+ more like the other jobs. Also start the async. job.
+ (file_list_cancel): Changed name for consistency and end the
+ async. job.
+ (directory_count_callback): End the async. job.
+ (start_monitoring_file_list): Start the async job.
+ (file_list_start): Moved logic about when to start loading the file
+ list into this function to make it more like other jobs.
+ (directory_count_start): Renamed to make it more like other jobs
+ and start the async. job.
+ (deep_count_callback): End the async. job.
+ (deep_count_start): Start the async. job.
+ (mime_list_callback): End the async. job.
+ (mime_list_start): Start the async. job.
+ (top_left_read_done): End the async. job.
+ (top_left_start): Start the async. job.
+ (get_info_callback): End the async. job.
+ (file_info_start): Start the async. job.
+ (activation_uri_done): End the async. job.
+ (activation_uri_start): Start the async. job.
+ (nautilus_directory_async_state_changed): Wake up directories that
+ may have breathing from from all the cancellation.
+ (nautilus_directory_cancel): Moved the cancelling code down here,
+ remove a directory from the waiting list when it goes, and also
+ wake up directories that may have breathing room from all the
+ cancellation.
+
+ * libnautilus-extensions/nautilus-directory-private.h: Remove
+ request_read_metafile from the header.
+
+ * libnautilus-extensions/nautilus-directory.c:
+ (nautilus_directory_destroy): Eliminate the call to
+ nautilus_directory_stop_monitoring_file_list since that's now
+ handled by nautilus_directory_cancel.
+
+ * libnautilus-extensions/nautilus-file-private.h: Removed the
+ got_*_mime_type variables since they are the same as *_mime_type
+ != NULL.
+
+ * libnautilus-extensions/nautilus-file.c: (destroy): Get rid of
+ checks for NULL before calling g_free.
+ (nautilus_file_update_info): Replace == FALSE with !. Simplified
+ some tortuous logic by getting rid of checks for NULL that weren't
+ needed and booleans that weren't needed.
+ (get_either_mime_type): Add helper to make it easier to avoid
+ confusion between default and slow MIME type.
+ (nautilus_file_compare_by_type): Use get_either_mime_type so it
+ works when default MIME type is NULL.
+ (nautilus_file_get_type_as_string): Use get_either_mime_type so it
+ works when default MIME type is NULL.
+ (nautilus_file_get_slow_mime_type): Simplified logic. Also got rid
+ of "application/nonono" which was left here by accident.
+ (nautilus_file_get_mime_type): Simplified logic and use
+ get_either_mime_type to share code.
+ (nautilus_file_is_mime_type): Simplified logic and use
+ get_either_mime_type to share code.
+
+ * src/file-manager/fm-directory-view.c: Format tweaks.
+
+ * user-guide/C/Makefile.am: Not so much echoing as we install.
+
2000-10-17 Gene Z. Ragan <gzr@eazel.com>
Fixed bug 3716, Bonobo paths for applications and
@@ -2950,6 +3027,7 @@
parameter-failure crash a few levels deep.
2000-10-06 Rebecca Schulman <rebecka@eazel.com>
+
* libnautilus-extensions/nautilus-directory-async.c:
* libnautilus-extensions/nautilus-directory-private.h:
(set_up_request_by_file_attributes),
diff --git a/check-FIXME.pl b/check-FIXME.pl
index 7ca073a43..42cbbebf8 100755
--- a/check-FIXME.pl
+++ b/check-FIXME.pl
@@ -33,7 +33,7 @@ use strict;
my %skip_files;
if (!@ARGV)
{
- @ARGV = `find . \\( \\( -name po -prune -false \\) -or \\( -name CVS -prune -false \\) -or \\( -name '*' -and -type f \\) \\) -and ! \\( -name '*~' -or -name '#*' -or -name 'ChangeLog*' -or -name Entries \\) -print`;
+ @ARGV = `find . \\( \\( -name po -prune -false \\) -or \\( -name CVS -prune -false \\) -or \\( -name macros -prune -false \\) -or \\( -name '*' -and -type f \\) \\) -and ! \\( -name '*~' -or -name '#*' -or -name 'ChangeLog*' -or -name Entries \\) -print`;
%skip_files =
(
"./HACKING" => 1,
diff --git a/libnautilus-extensions/nautilus-directory-async.c b/libnautilus-extensions/nautilus-directory-async.c
index 81ab8dbd2..faf42b1f1 100644
--- a/libnautilus-extensions/nautilus-directory-async.c
+++ b/libnautilus-extensions/nautilus-directory-async.c
@@ -106,26 +106,116 @@ typedef struct {
typedef gboolean (* RequestCheck) (const Request *);
typedef gboolean (* FileCheck) (NautilusFile *);
+/* Keep async. jobs down to this number for all directories. */
+#define MAX_ASYNC_JOBS 10
+
+/* Current number of async. jobs. */
+static int async_job_count;
+static GHashTable *waiting_directories;
+
/* Forward declarations for functions that need them. */
-static void deep_count_load (NautilusDirectory *directory,
- const char *uri);
-static void metafile_read_start (NautilusDirectory *directory);
-static gboolean request_is_satisfied (NautilusDirectory *directory,
- NautilusFile *file,
- Request *request);
+static void deep_count_load (NautilusDirectory *directory,
+ const char *uri);
+static void metafile_read_restart (NautilusDirectory *directory);
+static gboolean request_is_satisfied (NautilusDirectory *directory,
+ NautilusFile *file,
+ Request *request);
+
+/* Start a job. This is really just a way of limiting the number of
+ * async. requests that we issue at any given time. Without this, the
+ * number of requests is unbounded.
+ */
+static gboolean
+async_job_start (NautilusDirectory *directory)
+{
+ g_assert (async_job_count >= 0);
+ g_assert (async_job_count <= MAX_ASYNC_JOBS);
+
+ if (async_job_count >= MAX_ASYNC_JOBS) {
+ if (waiting_directories == NULL) {
+ waiting_directories = nautilus_g_hash_table_new_free_at_exit
+ (g_direct_hash, g_direct_equal,
+ "nautilus-directory-async.c: waiting_directories");
+ }
+
+ g_hash_table_insert (waiting_directories,
+ directory,
+ directory);
+
+ return FALSE;
+ }
+ async_job_count += 1;
+ return TRUE;
+}
+
+/* End a job. */
static void
-cancel_directory_counts (NautilusDirectory *directory)
+async_job_end (void)
+{
+ g_assert (async_job_count > 0);
+
+ async_job_count -= 1;
+}
+
+/* Helper to extract one value from a hash table. */
+static void
+get_one_value_callback (gpointer key, gpointer value, gpointer callback_data)
+{
+ gpointer *returned_value;
+
+ returned_value = callback_data;
+ *returned_value = value;
+}
+
+/* Extract a single value from a hash table. */
+static gpointer
+get_one_value (GHashTable *table)
+{
+ gpointer value;
+
+ value = NULL;
+ if (table != NULL) {
+ g_hash_table_foreach (table, get_one_value_callback, &value);
+ }
+ return value;
+}
+
+/* Wake up directories that are "blocked" as long as there are job
+ * slots available.
+ */
+static void
+async_job_wake_up (void)
+{
+ gpointer value;
+
+ g_assert (async_job_count >= 0);
+ g_assert (async_job_count <= MAX_ASYNC_JOBS);
+
+ while (async_job_count < MAX_ASYNC_JOBS) {
+ value = get_one_value (waiting_directories);
+ if (value == NULL) {
+ break;
+ }
+ nautilus_directory_async_state_changed
+ (NAUTILUS_DIRECTORY (value));
+ }
+}
+
+static void
+directory_count_cancel (NautilusDirectory *directory)
{
if (directory->details->count_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->count_in_progress);
directory->details->count_file = NULL;
directory->details->count_in_progress = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_deep_count (NautilusDirectory *directory)
+deep_count_cancel (NautilusDirectory *directory)
{
if (directory->details->deep_count_in_progress != NULL) {
g_assert (NAUTILUS_IS_FILE (directory->details->deep_count_file));
@@ -140,11 +230,13 @@ cancel_deep_count (NautilusDirectory *directory)
directory->details->deep_count_uri = NULL;
nautilus_g_list_free_deep (directory->details->deep_count_subdirectories);
directory->details->deep_count_subdirectories = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_mime_list (NautilusDirectory *directory)
+mime_list_cancel (NautilusDirectory *directory)
{
if (directory->details->mime_list_in_progress != NULL) {
g_assert (NAUTILUS_IS_FILE (directory->details->mime_list_file));
@@ -157,41 +249,49 @@ cancel_mime_list (NautilusDirectory *directory)
directory->details->mime_list_in_progress = NULL;
g_free (directory->details->mime_list_uri);
directory->details->mime_list_uri = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_top_left_read (NautilusDirectory *directory)
+top_left_cancel (NautilusDirectory *directory)
{
if (directory->details->top_left_read_state != NULL) {
nautilus_read_file_cancel (directory->details->top_left_read_state->handle);
g_free (directory->details->top_left_read_state);
directory->details->top_left_read_state = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_get_activation_uri (NautilusDirectory *directory)
+activation_uri_cancel (NautilusDirectory *directory)
{
if (directory->details->activation_uri_read_state != NULL) {
nautilus_read_file_cancel (directory->details->activation_uri_read_state->handle);
g_free (directory->details->activation_uri_read_state);
directory->details->activation_uri_read_state = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_get_info (NautilusDirectory *directory)
+file_info_cancel (NautilusDirectory *directory)
{
if (directory->details->get_info_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->get_info_in_progress);
directory->details->get_info_file = NULL;
directory->details->get_info_in_progress = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_metafile_read (NautilusDirectory *directory)
+metafile_read_cancel (NautilusDirectory *directory)
{
if (directory->details->metafile_read_state != NULL) {
if (directory->details->metafile_read_state->handle != NULL) {
@@ -202,19 +302,9 @@ cancel_metafile_read (NautilusDirectory *directory)
}
g_free (directory->details->metafile_read_state);
directory->details->metafile_read_state = NULL;
- }
-}
-void
-nautilus_directory_cancel (NautilusDirectory *directory)
-{
- cancel_deep_count (directory);
- cancel_directory_counts (directory);
- cancel_mime_list (directory);
- cancel_get_info (directory);
- cancel_metafile_read (directory);
- cancel_top_left_read (directory);
- cancel_get_activation_uri (directory);
+ async_job_end ();
+ }
}
static gboolean
@@ -259,6 +349,7 @@ metafile_read_done (NautilusDirectory *directory)
nautilus_directory_emit_metadata_changed (directory);
/* Let the callers that were waiting for the metafile know. */
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -266,7 +357,7 @@ static void
metafile_read_try_public_metafile (NautilusDirectory *directory)
{
directory->details->metafile_read_state->use_public_metafile = TRUE;
- metafile_read_start (directory);
+ metafile_read_restart (directory);
}
static void
@@ -403,7 +494,7 @@ metafile_read_done_callback (GnomeVFSResult result,
}
static void
-metafile_read_start (NautilusDirectory *directory)
+metafile_read_restart (NautilusDirectory *directory)
{
char *text_uri;
@@ -455,8 +546,33 @@ allow_metafile (NautilusDirectory *directory)
return TRUE;
}
-void
-nautilus_directory_request_read_metafile (NautilusDirectory *directory)
+/* This checks if there's a request for the metafile contents. */
+static gboolean
+is_anyone_waiting_for_metafile (NautilusDirectory *directory)
+{
+ GList *node;
+ ReadyCallback *callback;
+ Monitor *monitor;
+
+ for (node = directory->details->call_when_ready_list; node != NULL; node = node->next) {
+ callback = node->data;
+ if (callback->request.metafile) {
+ return TRUE;
+ }
+ }
+
+ for (node = directory->details->monitor_list; node != NULL; node = node->next) {
+ monitor = node->data;
+ if (monitor->request.metafile) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+metafile_read_start (NautilusDirectory *directory)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
@@ -467,11 +583,18 @@ nautilus_directory_request_read_metafile (NautilusDirectory *directory)
g_assert (directory->details->metafile == NULL);
+ if (!is_anyone_waiting_for_metafile (directory)) {
+ return;
+ }
+
if (!allow_metafile (directory)) {
metafile_read_done (directory);
} else {
+ if (!async_job_start (directory)) {
+ return;
+ }
directory->details->metafile_read_state = g_new0 (MetafileReadState, 1);
- metafile_read_start (directory);
+ metafile_read_restart (directory);
}
}
@@ -925,6 +1048,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
/* If we are no longer monitoring, then throw away these. */
if (!nautilus_directory_is_file_list_monitored (directory)) {
gnome_vfs_file_info_list_free (pending_file_info);
+
nautilus_directory_async_state_changed (directory);
return FALSE;
}
@@ -1026,11 +1150,12 @@ directory_load_one (NautilusDirectory *directory,
}
static void
-cancel_directory_load (NautilusDirectory *directory)
+file_list_cancel (NautilusDirectory *directory)
{
if (directory->details->directory_load_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->directory_load_in_progress);
directory->details->directory_load_in_progress = NULL;
+ async_job_end ();
}
}
@@ -1040,7 +1165,7 @@ directory_load_done (NautilusDirectory *directory,
{
GList *node;
- cancel_directory_load (directory);
+ file_list_cancel (directory);
directory->details->directory_loaded = TRUE;
directory->details->directory_loaded_sent_notification = FALSE;
@@ -1241,12 +1366,11 @@ nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
NautilusFile *file,
GList *file_attributes)
{
- Request request = {};
+ Request request;
- g_assert (directory != NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
set_up_request_by_file_attributes (&request, file_attributes);
-
return request_is_satisfied (directory, file, &request);
}
@@ -1341,6 +1465,7 @@ directory_count_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (count_file);
/* Start up the next one. */
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -1689,31 +1814,6 @@ nautilus_directory_is_anyone_monitoring_file_list (NautilusDirectory *directory)
return FALSE;
}
-/* This checks if there's a request for the metafile contents. */
-static gboolean
-is_anyone_waiting_for_metafile (NautilusDirectory *directory)
-{
- GList *node;
- ReadyCallback *callback;
- Monitor *monitor;
-
- for (node = directory->details->call_when_ready_list; node != NULL; node = node->next) {
- callback = node->data;
- if (callback->request.metafile) {
- return TRUE;
- }
- }
-
- for (node = directory->details->monitor_list; node != NULL; node = node->next) {
- monitor = node->data;
- if (monitor->request.metafile) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
/* This checks if the file list being monitored. */
gboolean
nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
@@ -1749,6 +1849,10 @@ start_monitoring_file_list (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
mark_all_files_unconfirmed (directory);
g_assert (directory->details->uri != NULL);
@@ -1783,12 +1887,22 @@ nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory)
}
directory->details->file_list_monitored = FALSE;
- cancel_directory_load (directory);
+ file_list_cancel (directory);
nautilus_file_list_unref (directory->details->file_list);
directory->details->directory_loaded = FALSE;
}
+static void
+file_list_start (NautilusDirectory *directory)
+{
+ if (nautilus_directory_is_anyone_monitoring_file_list (directory)) {
+ start_monitoring_file_list (directory);
+ } else {
+ nautilus_directory_stop_monitoring_file_list (directory);
+ }
+}
+
void
nautilus_directory_invalidate_counts (NautilusDirectory *directory)
{
@@ -1800,13 +1914,13 @@ nautilus_directory_invalidate_counts (NautilusDirectory *directory)
parent_directory = file->details->directory;
if (parent_directory->details->count_file == file) {
- cancel_directory_counts (parent_directory);
+ directory_count_cancel (parent_directory);
}
if (parent_directory->details->deep_count_file == file) {
- cancel_deep_count (parent_directory);
+ deep_count_cancel (parent_directory);
}
if (parent_directory->details->mime_list_file == file) {
- cancel_mime_list (parent_directory);
+ mime_list_cancel (parent_directory);
}
file->details->got_directory_count = FALSE;
@@ -1829,7 +1943,7 @@ void
nautilus_directory_force_reload (NautilusDirectory *directory)
{
/* Start a new directory load. */
- cancel_directory_load (directory);
+ file_list_cancel (directory);
directory->details->directory_loaded = FALSE;
/* Start a new directory count. */
@@ -1994,7 +2108,7 @@ get_filter_options_for_directory_count (NautilusFile *file)
static void
-start_getting_directory_counts (NautilusDirectory *directory)
+directory_count_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2015,7 +2129,7 @@ start_getting_directory_counts (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_directory_counts (directory);
+ directory_count_cancel (directory);
}
/* Figure out which file to get a count for. */
@@ -2026,6 +2140,10 @@ start_getting_directory_counts (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
directory->details->count_file = file;
uri = nautilus_file_get_uri (file);
@@ -2137,6 +2255,7 @@ deep_count_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (file);
if (done) {
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
}
@@ -2188,7 +2307,7 @@ deep_count_start (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_deep_count (directory);
+ deep_count_cancel (directory);
}
/* Figure out which file to get a count for. */
@@ -2199,6 +2318,10 @@ deep_count_start (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
file->details->deep_counts_status = NAUTILUS_REQUEST_IN_PROGRESS;
file->details->deep_directory_count = 0;
@@ -2219,7 +2342,7 @@ mime_list_one (NautilusDirectory *directory,
file = directory->details->mime_list_file;
- if (g_list_find_custom (file->details->mime_list, info->mime_type, (GCompareFunc)g_strcasecmp) == NULL) {
+ if (g_list_find_custom (file->details->mime_list, info->mime_type, (GCompareFunc) g_strcasecmp) == NULL) {
file->details->mime_list = g_list_prepend (file->details->mime_list, g_strdup (info->mime_type));
}
}
@@ -2269,6 +2392,7 @@ mime_list_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (file);
if (done) {
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
}
@@ -2320,7 +2444,7 @@ mime_list_start (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_mime_list (directory);
+ mime_list_cancel (directory);
}
/* Figure out which file to get a mime list for. */
@@ -2331,6 +2455,10 @@ mime_list_start (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
file->details->mime_list_status = NAUTILUS_REQUEST_IN_PROGRESS;
/* FIXME: clear out mime_list_whatever */
@@ -2363,6 +2491,7 @@ top_left_read_done (NautilusDirectory *directory)
g_free (directory->details->top_left_read_state);
directory->details->top_left_read_state = NULL;
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -2404,7 +2533,7 @@ top_left_read_more_callback (GnomeVFSFileSize bytes_read,
}
static void
-start_getting_top_lefts (NautilusDirectory *directory)
+top_left_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2425,7 +2554,7 @@ start_getting_top_lefts (NautilusDirectory *directory)
}
/* The top left is not wanted, so stop it. */
- cancel_top_left_read (directory);
+ top_left_cancel (directory);
}
/* Figure out which file to read the top left for. */
@@ -2436,6 +2565,10 @@ start_getting_top_lefts (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start reading. */
directory->details->top_left_read_state = g_new0 (TopLeftTextReadState, 1);
directory->details->top_left_read_state->file = file;
@@ -2458,7 +2591,6 @@ get_info_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSGetFileInfoResult *result;
gboolean got_slow_mime_type;
- g_assert (NAUTILUS_IS_DIRECTORY (callback_data));
directory = NAUTILUS_DIRECTORY (callback_data);
got_slow_mime_type = directory->details->get_slow_mime_type_for_file;
g_assert (handle == NULL || handle == directory->details->get_info_in_progress);
@@ -2478,11 +2610,13 @@ get_info_callback (GnomeVFSAsyncHandle *handle,
got_slow_mime_type);
}
nautilus_file_changed (get_info_file);
+
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
static void
-start_getting_file_info (NautilusDirectory *directory)
+file_info_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2504,7 +2638,7 @@ start_getting_file_info (NautilusDirectory *directory)
}
/* The info is not wanted, so stop it. */
- cancel_get_info (directory);
+ file_info_cancel (directory);
}
/* Figure out which file to get file info for. */
@@ -2533,30 +2667,25 @@ start_getting_file_info (NautilusDirectory *directory)
} while (vfs_uri == NULL);
/* Found one we need to get the info for. */
+ if (!async_job_start (directory)) {
+ return;
+ }
directory->details->get_info_file = file;
directory->details->get_slow_mime_type_for_file = get_slow_mime_type;
fake_list.data = vfs_uri;
fake_list.prev = NULL;
fake_list.next = NULL;
- if (get_slow_mime_type) {
- gnome_vfs_async_get_file_info
- (&directory->details->get_info_in_progress,
- &fake_list,
- (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
- get_info_callback,
- directory);
- }
- else {
- gnome_vfs_async_get_file_info
- (&directory->details->get_info_in_progress,
- &fake_list,
- (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
- get_info_callback,
- directory);
- }
+ gnome_vfs_async_get_file_info
+ (&directory->details->get_info_in_progress,
+ &fake_list,
+ get_slow_mime_type
+ ? (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)
+ : (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
+ get_info_callback,
+ directory);
gnome_vfs_uri_unref (vfs_uri);
}
@@ -2569,6 +2698,7 @@ activation_uri_done (NautilusDirectory *directory,
g_free (file->details->activation_uri);
file->details->activation_uri = g_strdup (uri);
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -2656,7 +2786,7 @@ activation_uri_gmc_link_read_more_callback (GnomeVFSFileSize bytes_read,
}
static void
-start_getting_activation_uris (NautilusDirectory *directory)
+activation_uri_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *mime_type, *uri;
@@ -2676,7 +2806,7 @@ start_getting_activation_uris (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_get_activation_uri (directory);
+ activation_uri_cancel (directory);
}
/* Figure out which file to get activation_uri for. */
@@ -2687,12 +2817,16 @@ start_getting_activation_uris (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Figure out if it is a link. */
mime_type = nautilus_file_get_mime_type (file);
gmc_style_link = nautilus_strcasecmp (mime_type, "application/x-gmc-link") == 0;
g_free (mime_type);
nautilus_style_link = nautilus_file_is_nautilus_link (file);
-
+
/* If it's not a link we are done. If it is, we need to read it. */
if (!(gmc_style_link || nautilus_style_link)) {
activation_uri_done (directory, file, NULL);
@@ -2713,7 +2847,6 @@ start_getting_activation_uris (NautilusDirectory *directory)
directory);
}
g_free (uri);
-
}
}
@@ -2721,34 +2854,28 @@ static void
start_or_stop_io (NautilusDirectory *directory)
{
/* Start or stop getting file info. */
- start_getting_file_info (directory);
+ file_info_start (directory);
/* Start or stop reading the metafile. */
- if (is_anyone_waiting_for_metafile (directory)) {
- nautilus_directory_request_read_metafile (directory);
- }
+ metafile_read_start (directory);
/* Start or stop reading files. */
- if (nautilus_directory_is_anyone_monitoring_file_list (directory)) {
- start_monitoring_file_list (directory);
- } else {
- nautilus_directory_stop_monitoring_file_list (directory);
- }
+ file_list_start (directory);
/* Start or stop getting directory counts. */
- start_getting_directory_counts (directory);
+ directory_count_start (directory);
deep_count_start (directory);
/* Start or stop getting mime lists. */
mime_list_start (directory);
/* Start or stop getting top left pieces of files. */
- start_getting_top_lefts (directory);
+ top_left_start (directory);
/* Start or stop getting activation URIs, which includes
* reading the contents of Nautilus and GMC link files.
*/
- start_getting_activation_uris (directory);
+ activation_uri_start (directory);
}
/* Call this when the monitor or call when ready list changes,
@@ -2769,4 +2896,29 @@ nautilus_directory_async_state_changed (NautilusDirectory *directory)
start_or_stop_io (directory);
} while (call_ready_callbacks (directory));
nautilus_directory_unref (directory);
+
+ /* Check if any directories should wake up. */
+ async_job_wake_up ();
+}
+
+void
+nautilus_directory_cancel (NautilusDirectory *directory)
+{
+ /* Arbitrary order (kept alphabetical). */
+ activation_uri_cancel (directory);
+ deep_count_cancel (directory);
+ directory_count_cancel (directory);
+ file_info_cancel (directory);
+ file_list_cancel (directory);
+ metafile_read_cancel (directory);
+ mime_list_cancel (directory);
+ top_left_cancel (directory);
+
+ /* We aren't waiting for anything any more. */
+ if (waiting_directories != NULL) {
+ g_hash_table_remove (waiting_directories, directory);
+ }
+
+ /* Check if any directories should wake up. */
+ async_job_wake_up ();
}
diff --git a/libnautilus-extensions/nautilus-directory-private.h b/libnautilus-extensions/nautilus-directory-private.h
index 0961956cc..76b4d5a59 100644
--- a/libnautilus-extensions/nautilus-directory-private.h
+++ b/libnautilus-extensions/nautilus-directory-private.h
@@ -133,7 +133,6 @@ gboolean nautilus_directory_is_file_list_monitored (NautilusDi
gboolean nautilus_directory_is_anyone_monitoring_file_list (NautilusDirectory *directory);
void nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link);
-void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c
index dc3c009ba..be028c644 100644
--- a/libnautilus-extensions/nautilus-directory.c
+++ b/libnautilus-extensions/nautilus-directory.c
@@ -159,8 +159,6 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->top_left_read_state == NULL);
- nautilus_directory_stop_monitoring_file_list (directory);
-
if (directory->details->monitor_list != NULL) {
g_warning ("destroying a NautilusDirectory while it's being monitored");
nautilus_g_list_free_deep (directory->details->monitor_list);
diff --git a/libnautilus-extensions/nautilus-file-private.h b/libnautilus-extensions/nautilus-file-private.h
index b65dd03ac..5e47c7329 100644
--- a/libnautilus-extensions/nautilus-file-private.h
+++ b/libnautilus-extensions/nautilus-file-private.h
@@ -37,13 +37,12 @@ struct NautilusFileDetails
gboolean get_info_failed;
GnomeVFSResult get_info_error;
- /* Since the file info doesn't remember what mime type
- it got, we'll just keep them here, where it
- is clear what kind of mime type they are */
+ /* Since the file info doesn't remember what kind of mime type
+ * it got, we'll just keep them here, where it is clear what
+ * kind of mime type they are.
+ */
char *default_mime_type;
- gboolean got_default_mime_type;
char *slow_mime_type;
- gboolean got_slow_mime_type;
gboolean got_directory_count;
gboolean directory_count_failed;
diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c
index 6383fd1c6..caf5b34d4 100644
--- a/libnautilus-extensions/nautilus-file.c
+++ b/libnautilus-extensions/nautilus-file.c
@@ -398,12 +398,8 @@ destroy (GtkObject *object)
} else {
gnome_vfs_file_info_unref (file->details->info);
}
- if (file->details->got_default_mime_type) {
- g_free (file->details->default_mime_type);
- }
- if (file->details->got_slow_mime_type) {
- g_free (file->details->slow_mime_type);
- }
+ g_free (file->details->default_mime_type);
+ g_free (file->details->slow_mime_type);
g_free (file->details->top_left_text);
g_free (file->details->activation_uri);
@@ -1110,7 +1106,7 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info,
if (file->details->info != NULL
&& gnome_vfs_file_info_matches (file->details->info, info)
- && got_slow_mime_type == FALSE) {
+ && !got_slow_mime_type) {
return FALSE;
}
@@ -1125,24 +1121,12 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info,
gnome_vfs_file_info_unref (file->details->info);
}
file->details->info = info;
- if (info->mime_type == NULL) {
- g_warning ("help: this file has no mime type ! %s\n", info->name);
+ if (got_slow_mime_type) {
+ g_free (file->details->slow_mime_type);
+ file->details->slow_mime_type = g_strdup (info->mime_type);
} else {
-
- if (got_slow_mime_type) {
- if (file->details->got_slow_mime_type) {
- g_free (file->details->slow_mime_type);
- }
- file->details->got_slow_mime_type = TRUE;
- file->details->slow_mime_type = g_strdup (info->mime_type);
- }
- else {
- if (file->details->got_default_mime_type) {
- g_free (file->details->default_mime_type);
- }
- file->details->got_default_mime_type = TRUE;
- file->details->default_mime_type = g_strdup (info->mime_type);
- }
+ g_free (file->details->default_mime_type);
+ file->details->default_mime_type = g_strdup (info->mime_type);
}
file->details->name = info->name;
nautilus_directory_end_file_name_change (file->details->directory,
@@ -1386,6 +1370,18 @@ nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
return compare_result;
}
+static const char *
+get_either_mime_type (NautilusFile *file)
+{
+ /* Always prefer the non-slow type since that's updated more
+ * often. This doesn't sound quite right, but I guess it's OK.
+ */
+ if (file->details->default_mime_type != NULL) {
+ return file->details->default_mime_type;
+ }
+ return file->details->slow_mime_type;
+}
+
static int
nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
{
@@ -1415,11 +1411,10 @@ nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
return +1;
}
-
if (file_1->details->info != NULL
&& file_2->details->info != NULL
- && nautilus_strcmp (file_1->details->default_mime_type,
- file_2->details->default_mime_type) == 0) {
+ && nautilus_strcmp (get_either_mime_type (file_1),
+ get_either_mime_type (file_2)) == 0) {
return 0;
}
@@ -3346,10 +3341,7 @@ nautilus_file_get_type_as_string (NautilusFile *file)
return g_strdup (_("link (broken)"));
}
- mime_type = file->details->slow_mime_type;
- if (mime_type == NULL) {
- mime_type = file->details->default_mime_type;
- }
+ mime_type = get_either_mime_type (file);
if (nautilus_strlen (mime_type) == 0) {
/* No mime type, anything else interesting we can say about this? */
@@ -3413,16 +3405,13 @@ nautilus_file_get_file_type (NautilusFile *file)
char *
nautilus_file_get_slow_mime_type (NautilusFile *file)
{
- g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
- if (file == NULL) {
- return g_strdup ("application/nonono");;
- }
- if (file->details->got_slow_mime_type) {
- return g_strdup (file->details->slow_mime_type);
- }
- else {
- return g_strdup ("application/octet-stream");
+ if (file != NULL) {
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+ if (file->details->slow_mime_type != NULL) {
+ return g_strdup (file->details->slow_mime_type);
+ }
}
+ return g_strdup ("application/octet-stream");
}
@@ -3439,22 +3428,16 @@ nautilus_file_get_slow_mime_type (NautilusFile *file)
char *
nautilus_file_get_mime_type (NautilusFile *file)
{
- if (file == NULL) {
- return g_strdup ("application/octet-stream");
- }
- if (file->details->got_default_mime_type == FALSE &&
- file->details->got_slow_mime_type == FALSE) {
- return g_strdup ("application/octet-stream");
- }
- if (file->details->got_default_mime_type) {
+ const char *mime_type;
- return g_strdup (file->details->default_mime_type);
- }
- else {
- return g_strdup (file->details->slow_mime_type);
+ if (file != NULL) {
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+ mime_type = get_either_mime_type (file);
+ if (mime_type != NULL) {
+ return g_strdup (mime_type);
+ }
}
-
-
+ return g_strdup ("application/octet-stream");
}
@@ -3472,20 +3455,16 @@ nautilus_file_get_mime_type (NautilusFile *file)
gboolean
nautilus_file_is_mime_type (NautilusFile *file, const char *mime_type)
{
- g_return_val_if_fail (mime_type != NULL, FALSE);
+ const char *file_mime_type;
- /* If we have no mime type information, never mind */
- if (file->details->got_default_mime_type == FALSE &&
- file->details->got_slow_mime_type == FALSE) {
- return FALSE;
- }
- if (file->details->got_slow_mime_type) {
- return nautilus_strcasecmp (file->details->slow_mime_type, mime_type) == 0;
- }
- else {
- return nautilus_strcasecmp (file->details->default_mime_type, mime_type) == 0;
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE);
+ g_return_val_if_fail (mime_type != NULL, FALSE);
+
+ file_mime_type = get_either_mime_type (file);
+ if (file_mime_type != NULL) {
+ return nautilus_strcasecmp (file_mime_type, mime_type) == 0;
}
-
+ return FALSE;
}
/**
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index 81ab8dbd2..faf42b1f1 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -106,26 +106,116 @@ typedef struct {
typedef gboolean (* RequestCheck) (const Request *);
typedef gboolean (* FileCheck) (NautilusFile *);
+/* Keep async. jobs down to this number for all directories. */
+#define MAX_ASYNC_JOBS 10
+
+/* Current number of async. jobs. */
+static int async_job_count;
+static GHashTable *waiting_directories;
+
/* Forward declarations for functions that need them. */
-static void deep_count_load (NautilusDirectory *directory,
- const char *uri);
-static void metafile_read_start (NautilusDirectory *directory);
-static gboolean request_is_satisfied (NautilusDirectory *directory,
- NautilusFile *file,
- Request *request);
+static void deep_count_load (NautilusDirectory *directory,
+ const char *uri);
+static void metafile_read_restart (NautilusDirectory *directory);
+static gboolean request_is_satisfied (NautilusDirectory *directory,
+ NautilusFile *file,
+ Request *request);
+
+/* Start a job. This is really just a way of limiting the number of
+ * async. requests that we issue at any given time. Without this, the
+ * number of requests is unbounded.
+ */
+static gboolean
+async_job_start (NautilusDirectory *directory)
+{
+ g_assert (async_job_count >= 0);
+ g_assert (async_job_count <= MAX_ASYNC_JOBS);
+
+ if (async_job_count >= MAX_ASYNC_JOBS) {
+ if (waiting_directories == NULL) {
+ waiting_directories = nautilus_g_hash_table_new_free_at_exit
+ (g_direct_hash, g_direct_equal,
+ "nautilus-directory-async.c: waiting_directories");
+ }
+
+ g_hash_table_insert (waiting_directories,
+ directory,
+ directory);
+
+ return FALSE;
+ }
+ async_job_count += 1;
+ return TRUE;
+}
+
+/* End a job. */
static void
-cancel_directory_counts (NautilusDirectory *directory)
+async_job_end (void)
+{
+ g_assert (async_job_count > 0);
+
+ async_job_count -= 1;
+}
+
+/* Helper to extract one value from a hash table. */
+static void
+get_one_value_callback (gpointer key, gpointer value, gpointer callback_data)
+{
+ gpointer *returned_value;
+
+ returned_value = callback_data;
+ *returned_value = value;
+}
+
+/* Extract a single value from a hash table. */
+static gpointer
+get_one_value (GHashTable *table)
+{
+ gpointer value;
+
+ value = NULL;
+ if (table != NULL) {
+ g_hash_table_foreach (table, get_one_value_callback, &value);
+ }
+ return value;
+}
+
+/* Wake up directories that are "blocked" as long as there are job
+ * slots available.
+ */
+static void
+async_job_wake_up (void)
+{
+ gpointer value;
+
+ g_assert (async_job_count >= 0);
+ g_assert (async_job_count <= MAX_ASYNC_JOBS);
+
+ while (async_job_count < MAX_ASYNC_JOBS) {
+ value = get_one_value (waiting_directories);
+ if (value == NULL) {
+ break;
+ }
+ nautilus_directory_async_state_changed
+ (NAUTILUS_DIRECTORY (value));
+ }
+}
+
+static void
+directory_count_cancel (NautilusDirectory *directory)
{
if (directory->details->count_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->count_in_progress);
directory->details->count_file = NULL;
directory->details->count_in_progress = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_deep_count (NautilusDirectory *directory)
+deep_count_cancel (NautilusDirectory *directory)
{
if (directory->details->deep_count_in_progress != NULL) {
g_assert (NAUTILUS_IS_FILE (directory->details->deep_count_file));
@@ -140,11 +230,13 @@ cancel_deep_count (NautilusDirectory *directory)
directory->details->deep_count_uri = NULL;
nautilus_g_list_free_deep (directory->details->deep_count_subdirectories);
directory->details->deep_count_subdirectories = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_mime_list (NautilusDirectory *directory)
+mime_list_cancel (NautilusDirectory *directory)
{
if (directory->details->mime_list_in_progress != NULL) {
g_assert (NAUTILUS_IS_FILE (directory->details->mime_list_file));
@@ -157,41 +249,49 @@ cancel_mime_list (NautilusDirectory *directory)
directory->details->mime_list_in_progress = NULL;
g_free (directory->details->mime_list_uri);
directory->details->mime_list_uri = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_top_left_read (NautilusDirectory *directory)
+top_left_cancel (NautilusDirectory *directory)
{
if (directory->details->top_left_read_state != NULL) {
nautilus_read_file_cancel (directory->details->top_left_read_state->handle);
g_free (directory->details->top_left_read_state);
directory->details->top_left_read_state = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_get_activation_uri (NautilusDirectory *directory)
+activation_uri_cancel (NautilusDirectory *directory)
{
if (directory->details->activation_uri_read_state != NULL) {
nautilus_read_file_cancel (directory->details->activation_uri_read_state->handle);
g_free (directory->details->activation_uri_read_state);
directory->details->activation_uri_read_state = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_get_info (NautilusDirectory *directory)
+file_info_cancel (NautilusDirectory *directory)
{
if (directory->details->get_info_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->get_info_in_progress);
directory->details->get_info_file = NULL;
directory->details->get_info_in_progress = NULL;
+
+ async_job_end ();
}
}
static void
-cancel_metafile_read (NautilusDirectory *directory)
+metafile_read_cancel (NautilusDirectory *directory)
{
if (directory->details->metafile_read_state != NULL) {
if (directory->details->metafile_read_state->handle != NULL) {
@@ -202,19 +302,9 @@ cancel_metafile_read (NautilusDirectory *directory)
}
g_free (directory->details->metafile_read_state);
directory->details->metafile_read_state = NULL;
- }
-}
-void
-nautilus_directory_cancel (NautilusDirectory *directory)
-{
- cancel_deep_count (directory);
- cancel_directory_counts (directory);
- cancel_mime_list (directory);
- cancel_get_info (directory);
- cancel_metafile_read (directory);
- cancel_top_left_read (directory);
- cancel_get_activation_uri (directory);
+ async_job_end ();
+ }
}
static gboolean
@@ -259,6 +349,7 @@ metafile_read_done (NautilusDirectory *directory)
nautilus_directory_emit_metadata_changed (directory);
/* Let the callers that were waiting for the metafile know. */
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -266,7 +357,7 @@ static void
metafile_read_try_public_metafile (NautilusDirectory *directory)
{
directory->details->metafile_read_state->use_public_metafile = TRUE;
- metafile_read_start (directory);
+ metafile_read_restart (directory);
}
static void
@@ -403,7 +494,7 @@ metafile_read_done_callback (GnomeVFSResult result,
}
static void
-metafile_read_start (NautilusDirectory *directory)
+metafile_read_restart (NautilusDirectory *directory)
{
char *text_uri;
@@ -455,8 +546,33 @@ allow_metafile (NautilusDirectory *directory)
return TRUE;
}
-void
-nautilus_directory_request_read_metafile (NautilusDirectory *directory)
+/* This checks if there's a request for the metafile contents. */
+static gboolean
+is_anyone_waiting_for_metafile (NautilusDirectory *directory)
+{
+ GList *node;
+ ReadyCallback *callback;
+ Monitor *monitor;
+
+ for (node = directory->details->call_when_ready_list; node != NULL; node = node->next) {
+ callback = node->data;
+ if (callback->request.metafile) {
+ return TRUE;
+ }
+ }
+
+ for (node = directory->details->monitor_list; node != NULL; node = node->next) {
+ monitor = node->data;
+ if (monitor->request.metafile) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+metafile_read_start (NautilusDirectory *directory)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
@@ -467,11 +583,18 @@ nautilus_directory_request_read_metafile (NautilusDirectory *directory)
g_assert (directory->details->metafile == NULL);
+ if (!is_anyone_waiting_for_metafile (directory)) {
+ return;
+ }
+
if (!allow_metafile (directory)) {
metafile_read_done (directory);
} else {
+ if (!async_job_start (directory)) {
+ return;
+ }
directory->details->metafile_read_state = g_new0 (MetafileReadState, 1);
- metafile_read_start (directory);
+ metafile_read_restart (directory);
}
}
@@ -925,6 +1048,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
/* If we are no longer monitoring, then throw away these. */
if (!nautilus_directory_is_file_list_monitored (directory)) {
gnome_vfs_file_info_list_free (pending_file_info);
+
nautilus_directory_async_state_changed (directory);
return FALSE;
}
@@ -1026,11 +1150,12 @@ directory_load_one (NautilusDirectory *directory,
}
static void
-cancel_directory_load (NautilusDirectory *directory)
+file_list_cancel (NautilusDirectory *directory)
{
if (directory->details->directory_load_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->directory_load_in_progress);
directory->details->directory_load_in_progress = NULL;
+ async_job_end ();
}
}
@@ -1040,7 +1165,7 @@ directory_load_done (NautilusDirectory *directory,
{
GList *node;
- cancel_directory_load (directory);
+ file_list_cancel (directory);
directory->details->directory_loaded = TRUE;
directory->details->directory_loaded_sent_notification = FALSE;
@@ -1241,12 +1366,11 @@ nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
NautilusFile *file,
GList *file_attributes)
{
- Request request = {};
+ Request request;
- g_assert (directory != NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
set_up_request_by_file_attributes (&request, file_attributes);
-
return request_is_satisfied (directory, file, &request);
}
@@ -1341,6 +1465,7 @@ directory_count_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (count_file);
/* Start up the next one. */
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -1689,31 +1814,6 @@ nautilus_directory_is_anyone_monitoring_file_list (NautilusDirectory *directory)
return FALSE;
}
-/* This checks if there's a request for the metafile contents. */
-static gboolean
-is_anyone_waiting_for_metafile (NautilusDirectory *directory)
-{
- GList *node;
- ReadyCallback *callback;
- Monitor *monitor;
-
- for (node = directory->details->call_when_ready_list; node != NULL; node = node->next) {
- callback = node->data;
- if (callback->request.metafile) {
- return TRUE;
- }
- }
-
- for (node = directory->details->monitor_list; node != NULL; node = node->next) {
- monitor = node->data;
- if (monitor->request.metafile) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
/* This checks if the file list being monitored. */
gboolean
nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
@@ -1749,6 +1849,10 @@ start_monitoring_file_list (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
mark_all_files_unconfirmed (directory);
g_assert (directory->details->uri != NULL);
@@ -1783,12 +1887,22 @@ nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory)
}
directory->details->file_list_monitored = FALSE;
- cancel_directory_load (directory);
+ file_list_cancel (directory);
nautilus_file_list_unref (directory->details->file_list);
directory->details->directory_loaded = FALSE;
}
+static void
+file_list_start (NautilusDirectory *directory)
+{
+ if (nautilus_directory_is_anyone_monitoring_file_list (directory)) {
+ start_monitoring_file_list (directory);
+ } else {
+ nautilus_directory_stop_monitoring_file_list (directory);
+ }
+}
+
void
nautilus_directory_invalidate_counts (NautilusDirectory *directory)
{
@@ -1800,13 +1914,13 @@ nautilus_directory_invalidate_counts (NautilusDirectory *directory)
parent_directory = file->details->directory;
if (parent_directory->details->count_file == file) {
- cancel_directory_counts (parent_directory);
+ directory_count_cancel (parent_directory);
}
if (parent_directory->details->deep_count_file == file) {
- cancel_deep_count (parent_directory);
+ deep_count_cancel (parent_directory);
}
if (parent_directory->details->mime_list_file == file) {
- cancel_mime_list (parent_directory);
+ mime_list_cancel (parent_directory);
}
file->details->got_directory_count = FALSE;
@@ -1829,7 +1943,7 @@ void
nautilus_directory_force_reload (NautilusDirectory *directory)
{
/* Start a new directory load. */
- cancel_directory_load (directory);
+ file_list_cancel (directory);
directory->details->directory_loaded = FALSE;
/* Start a new directory count. */
@@ -1994,7 +2108,7 @@ get_filter_options_for_directory_count (NautilusFile *file)
static void
-start_getting_directory_counts (NautilusDirectory *directory)
+directory_count_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2015,7 +2129,7 @@ start_getting_directory_counts (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_directory_counts (directory);
+ directory_count_cancel (directory);
}
/* Figure out which file to get a count for. */
@@ -2026,6 +2140,10 @@ start_getting_directory_counts (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
directory->details->count_file = file;
uri = nautilus_file_get_uri (file);
@@ -2137,6 +2255,7 @@ deep_count_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (file);
if (done) {
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
}
@@ -2188,7 +2307,7 @@ deep_count_start (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_deep_count (directory);
+ deep_count_cancel (directory);
}
/* Figure out which file to get a count for. */
@@ -2199,6 +2318,10 @@ deep_count_start (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
file->details->deep_counts_status = NAUTILUS_REQUEST_IN_PROGRESS;
file->details->deep_directory_count = 0;
@@ -2219,7 +2342,7 @@ mime_list_one (NautilusDirectory *directory,
file = directory->details->mime_list_file;
- if (g_list_find_custom (file->details->mime_list, info->mime_type, (GCompareFunc)g_strcasecmp) == NULL) {
+ if (g_list_find_custom (file->details->mime_list, info->mime_type, (GCompareFunc) g_strcasecmp) == NULL) {
file->details->mime_list = g_list_prepend (file->details->mime_list, g_strdup (info->mime_type));
}
}
@@ -2269,6 +2392,7 @@ mime_list_callback (GnomeVFSAsyncHandle *handle,
nautilus_file_changed (file);
if (done) {
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
}
@@ -2320,7 +2444,7 @@ mime_list_start (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_mime_list (directory);
+ mime_list_cancel (directory);
}
/* Figure out which file to get a mime list for. */
@@ -2331,6 +2455,10 @@ mime_list_start (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start counting. */
file->details->mime_list_status = NAUTILUS_REQUEST_IN_PROGRESS;
/* FIXME: clear out mime_list_whatever */
@@ -2363,6 +2491,7 @@ top_left_read_done (NautilusDirectory *directory)
g_free (directory->details->top_left_read_state);
directory->details->top_left_read_state = NULL;
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -2404,7 +2533,7 @@ top_left_read_more_callback (GnomeVFSFileSize bytes_read,
}
static void
-start_getting_top_lefts (NautilusDirectory *directory)
+top_left_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2425,7 +2554,7 @@ start_getting_top_lefts (NautilusDirectory *directory)
}
/* The top left is not wanted, so stop it. */
- cancel_top_left_read (directory);
+ top_left_cancel (directory);
}
/* Figure out which file to read the top left for. */
@@ -2436,6 +2565,10 @@ start_getting_top_lefts (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Start reading. */
directory->details->top_left_read_state = g_new0 (TopLeftTextReadState, 1);
directory->details->top_left_read_state->file = file;
@@ -2458,7 +2591,6 @@ get_info_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSGetFileInfoResult *result;
gboolean got_slow_mime_type;
- g_assert (NAUTILUS_IS_DIRECTORY (callback_data));
directory = NAUTILUS_DIRECTORY (callback_data);
got_slow_mime_type = directory->details->get_slow_mime_type_for_file;
g_assert (handle == NULL || handle == directory->details->get_info_in_progress);
@@ -2478,11 +2610,13 @@ get_info_callback (GnomeVFSAsyncHandle *handle,
got_slow_mime_type);
}
nautilus_file_changed (get_info_file);
+
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
static void
-start_getting_file_info (NautilusDirectory *directory)
+file_info_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *uri;
@@ -2504,7 +2638,7 @@ start_getting_file_info (NautilusDirectory *directory)
}
/* The info is not wanted, so stop it. */
- cancel_get_info (directory);
+ file_info_cancel (directory);
}
/* Figure out which file to get file info for. */
@@ -2533,30 +2667,25 @@ start_getting_file_info (NautilusDirectory *directory)
} while (vfs_uri == NULL);
/* Found one we need to get the info for. */
+ if (!async_job_start (directory)) {
+ return;
+ }
directory->details->get_info_file = file;
directory->details->get_slow_mime_type_for_file = get_slow_mime_type;
fake_list.data = vfs_uri;
fake_list.prev = NULL;
fake_list.next = NULL;
- if (get_slow_mime_type) {
- gnome_vfs_async_get_file_info
- (&directory->details->get_info_in_progress,
- &fake_list,
- (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
- get_info_callback,
- directory);
- }
- else {
- gnome_vfs_async_get_file_info
- (&directory->details->get_info_in_progress,
- &fake_list,
- (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
- get_info_callback,
- directory);
- }
+ gnome_vfs_async_get_file_info
+ (&directory->details->get_info_in_progress,
+ &fake_list,
+ get_slow_mime_type
+ ? (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)
+ : (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
+ | GNOME_VFS_FILE_INFO_FOLLOW_LINKS),
+ get_info_callback,
+ directory);
gnome_vfs_uri_unref (vfs_uri);
}
@@ -2569,6 +2698,7 @@ activation_uri_done (NautilusDirectory *directory,
g_free (file->details->activation_uri);
file->details->activation_uri = g_strdup (uri);
+ async_job_end ();
nautilus_directory_async_state_changed (directory);
}
@@ -2656,7 +2786,7 @@ activation_uri_gmc_link_read_more_callback (GnomeVFSFileSize bytes_read,
}
static void
-start_getting_activation_uris (NautilusDirectory *directory)
+activation_uri_start (NautilusDirectory *directory)
{
NautilusFile *file;
char *mime_type, *uri;
@@ -2676,7 +2806,7 @@ start_getting_activation_uris (NautilusDirectory *directory)
}
/* The count is not wanted, so stop it. */
- cancel_get_activation_uri (directory);
+ activation_uri_cancel (directory);
}
/* Figure out which file to get activation_uri for. */
@@ -2687,12 +2817,16 @@ start_getting_activation_uris (NautilusDirectory *directory)
return;
}
+ if (!async_job_start (directory)) {
+ return;
+ }
+
/* Figure out if it is a link. */
mime_type = nautilus_file_get_mime_type (file);
gmc_style_link = nautilus_strcasecmp (mime_type, "application/x-gmc-link") == 0;
g_free (mime_type);
nautilus_style_link = nautilus_file_is_nautilus_link (file);
-
+
/* If it's not a link we are done. If it is, we need to read it. */
if (!(gmc_style_link || nautilus_style_link)) {
activation_uri_done (directory, file, NULL);
@@ -2713,7 +2847,6 @@ start_getting_activation_uris (NautilusDirectory *directory)
directory);
}
g_free (uri);
-
}
}
@@ -2721,34 +2854,28 @@ static void
start_or_stop_io (NautilusDirectory *directory)
{
/* Start or stop getting file info. */
- start_getting_file_info (directory);
+ file_info_start (directory);
/* Start or stop reading the metafile. */
- if (is_anyone_waiting_for_metafile (directory)) {
- nautilus_directory_request_read_metafile (directory);
- }
+ metafile_read_start (directory);
/* Start or stop reading files. */
- if (nautilus_directory_is_anyone_monitoring_file_list (directory)) {
- start_monitoring_file_list (directory);
- } else {
- nautilus_directory_stop_monitoring_file_list (directory);
- }
+ file_list_start (directory);
/* Start or stop getting directory counts. */
- start_getting_directory_counts (directory);
+ directory_count_start (directory);
deep_count_start (directory);
/* Start or stop getting mime lists. */
mime_list_start (directory);
/* Start or stop getting top left pieces of files. */
- start_getting_top_lefts (directory);
+ top_left_start (directory);
/* Start or stop getting activation URIs, which includes
* reading the contents of Nautilus and GMC link files.
*/
- start_getting_activation_uris (directory);
+ activation_uri_start (directory);
}
/* Call this when the monitor or call when ready list changes,
@@ -2769,4 +2896,29 @@ nautilus_directory_async_state_changed (NautilusDirectory *directory)
start_or_stop_io (directory);
} while (call_ready_callbacks (directory));
nautilus_directory_unref (directory);
+
+ /* Check if any directories should wake up. */
+ async_job_wake_up ();
+}
+
+void
+nautilus_directory_cancel (NautilusDirectory *directory)
+{
+ /* Arbitrary order (kept alphabetical). */
+ activation_uri_cancel (directory);
+ deep_count_cancel (directory);
+ directory_count_cancel (directory);
+ file_info_cancel (directory);
+ file_list_cancel (directory);
+ metafile_read_cancel (directory);
+ mime_list_cancel (directory);
+ top_left_cancel (directory);
+
+ /* We aren't waiting for anything any more. */
+ if (waiting_directories != NULL) {
+ g_hash_table_remove (waiting_directories, directory);
+ }
+
+ /* Check if any directories should wake up. */
+ async_job_wake_up ();
}
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index 0961956cc..76b4d5a59 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -133,7 +133,6 @@ gboolean nautilus_directory_is_file_list_monitored (NautilusDi
gboolean nautilus_directory_is_anyone_monitoring_file_list (NautilusDirectory *directory);
void nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link);
-void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index dc3c009ba..be028c644 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -159,8 +159,6 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->top_left_read_state == NULL);
- nautilus_directory_stop_monitoring_file_list (directory);
-
if (directory->details->monitor_list != NULL) {
g_warning ("destroying a NautilusDirectory while it's being monitored");
nautilus_g_list_free_deep (directory->details->monitor_list);
diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h
index b65dd03ac..5e47c7329 100644
--- a/libnautilus-private/nautilus-file-private.h
+++ b/libnautilus-private/nautilus-file-private.h
@@ -37,13 +37,12 @@ struct NautilusFileDetails
gboolean get_info_failed;
GnomeVFSResult get_info_error;
- /* Since the file info doesn't remember what mime type
- it got, we'll just keep them here, where it
- is clear what kind of mime type they are */
+ /* Since the file info doesn't remember what kind of mime type
+ * it got, we'll just keep them here, where it is clear what
+ * kind of mime type they are.
+ */
char *default_mime_type;
- gboolean got_default_mime_type;
char *slow_mime_type;
- gboolean got_slow_mime_type;
gboolean got_directory_count;
gboolean directory_count_failed;
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 6383fd1c6..caf5b34d4 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -398,12 +398,8 @@ destroy (GtkObject *object)
} else {
gnome_vfs_file_info_unref (file->details->info);
}
- if (file->details->got_default_mime_type) {
- g_free (file->details->default_mime_type);
- }
- if (file->details->got_slow_mime_type) {
- g_free (file->details->slow_mime_type);
- }
+ g_free (file->details->default_mime_type);
+ g_free (file->details->slow_mime_type);
g_free (file->details->top_left_text);
g_free (file->details->activation_uri);
@@ -1110,7 +1106,7 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info,
if (file->details->info != NULL
&& gnome_vfs_file_info_matches (file->details->info, info)
- && got_slow_mime_type == FALSE) {
+ && !got_slow_mime_type) {
return FALSE;
}
@@ -1125,24 +1121,12 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info,
gnome_vfs_file_info_unref (file->details->info);
}
file->details->info = info;
- if (info->mime_type == NULL) {
- g_warning ("help: this file has no mime type ! %s\n", info->name);
+ if (got_slow_mime_type) {
+ g_free (file->details->slow_mime_type);
+ file->details->slow_mime_type = g_strdup (info->mime_type);
} else {
-
- if (got_slow_mime_type) {
- if (file->details->got_slow_mime_type) {
- g_free (file->details->slow_mime_type);
- }
- file->details->got_slow_mime_type = TRUE;
- file->details->slow_mime_type = g_strdup (info->mime_type);
- }
- else {
- if (file->details->got_default_mime_type) {
- g_free (file->details->default_mime_type);
- }
- file->details->got_default_mime_type = TRUE;
- file->details->default_mime_type = g_strdup (info->mime_type);
- }
+ g_free (file->details->default_mime_type);
+ file->details->default_mime_type = g_strdup (info->mime_type);
}
file->details->name = info->name;
nautilus_directory_end_file_name_change (file->details->directory,
@@ -1386,6 +1370,18 @@ nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
return compare_result;
}
+static const char *
+get_either_mime_type (NautilusFile *file)
+{
+ /* Always prefer the non-slow type since that's updated more
+ * often. This doesn't sound quite right, but I guess it's OK.
+ */
+ if (file->details->default_mime_type != NULL) {
+ return file->details->default_mime_type;
+ }
+ return file->details->slow_mime_type;
+}
+
static int
nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
{
@@ -1415,11 +1411,10 @@ nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
return +1;
}
-
if (file_1->details->info != NULL
&& file_2->details->info != NULL
- && nautilus_strcmp (file_1->details->default_mime_type,
- file_2->details->default_mime_type) == 0) {
+ && nautilus_strcmp (get_either_mime_type (file_1),
+ get_either_mime_type (file_2)) == 0) {
return 0;
}
@@ -3346,10 +3341,7 @@ nautilus_file_get_type_as_string (NautilusFile *file)
return g_strdup (_("link (broken)"));
}
- mime_type = file->details->slow_mime_type;
- if (mime_type == NULL) {
- mime_type = file->details->default_mime_type;
- }
+ mime_type = get_either_mime_type (file);
if (nautilus_strlen (mime_type) == 0) {
/* No mime type, anything else interesting we can say about this? */
@@ -3413,16 +3405,13 @@ nautilus_file_get_file_type (NautilusFile *file)
char *
nautilus_file_get_slow_mime_type (NautilusFile *file)
{
- g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
- if (file == NULL) {
- return g_strdup ("application/nonono");;
- }
- if (file->details->got_slow_mime_type) {
- return g_strdup (file->details->slow_mime_type);
- }
- else {
- return g_strdup ("application/octet-stream");
+ if (file != NULL) {
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+ if (file->details->slow_mime_type != NULL) {
+ return g_strdup (file->details->slow_mime_type);
+ }
}
+ return g_strdup ("application/octet-stream");
}
@@ -3439,22 +3428,16 @@ nautilus_file_get_slow_mime_type (NautilusFile *file)
char *
nautilus_file_get_mime_type (NautilusFile *file)
{
- if (file == NULL) {
- return g_strdup ("application/octet-stream");
- }
- if (file->details->got_default_mime_type == FALSE &&
- file->details->got_slow_mime_type == FALSE) {
- return g_strdup ("application/octet-stream");
- }
- if (file->details->got_default_mime_type) {
+ const char *mime_type;
- return g_strdup (file->details->default_mime_type);
- }
- else {
- return g_strdup (file->details->slow_mime_type);
+ if (file != NULL) {
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+ mime_type = get_either_mime_type (file);
+ if (mime_type != NULL) {
+ return g_strdup (mime_type);
+ }
}
-
-
+ return g_strdup ("application/octet-stream");
}
@@ -3472,20 +3455,16 @@ nautilus_file_get_mime_type (NautilusFile *file)
gboolean
nautilus_file_is_mime_type (NautilusFile *file, const char *mime_type)
{
- g_return_val_if_fail (mime_type != NULL, FALSE);
+ const char *file_mime_type;
- /* If we have no mime type information, never mind */
- if (file->details->got_default_mime_type == FALSE &&
- file->details->got_slow_mime_type == FALSE) {
- return FALSE;
- }
- if (file->details->got_slow_mime_type) {
- return nautilus_strcasecmp (file->details->slow_mime_type, mime_type) == 0;
- }
- else {
- return nautilus_strcasecmp (file->details->default_mime_type, mime_type) == 0;
+ g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE);
+ g_return_val_if_fail (mime_type != NULL, FALSE);
+
+ file_mime_type = get_either_mime_type (file);
+ if (file_mime_type != NULL) {
+ return nautilus_strcasecmp (file_mime_type, mime_type) == 0;
}
-
+ return FALSE;
}
/**
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index 4a73b3705..5e10954d8 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -4134,8 +4134,9 @@ fm_directory_view_move_copy_items (const GList *item_uris,
relative_item_points[index].y += y;
}
}
- nautilus_file_operations_copy_move (item_uris, relative_item_points,
- target_dir, copy_action, GTK_WIDGET (view));
+ nautilus_file_operations_copy_move
+ (item_uris, relative_item_points,
+ target_dir, copy_action, GTK_WIDGET (view));
}
gboolean
@@ -4153,7 +4154,8 @@ fm_directory_view_can_accept_item (NautilusFile *target_item,
static gboolean
menu_item_matches_path (GtkMenuItem *item, const char *path)
{
- return nautilus_strcmp ((const char *)gtk_object_get_data (GTK_OBJECT (item), "path"), path) == 0;
+ return nautilus_strcmp ((const char *) gtk_object_get_data (GTK_OBJECT (item), "path"),
+ path) == 0;
}
/**
diff --git a/user-guide/C/Makefile.am b/user-guide/C/Makefile.am
index 93b0ff39a..95edf6efc 100644
--- a/user-guide/C/Makefile.am
+++ b/user-guide/C/Makefile.am
@@ -18,7 +18,6 @@ install-data-local:
else \
for i in $$installfiles; do \
basefile=`basename $$i`; \
- echo "-- Installing $$i" ; \
$(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR)$$basefile; \
done; \
fi