diff options
-rw-r--r-- | ChangeLog | 78 | ||||
-rwxr-xr-x | check-FIXME.pl | 2 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-directory-async.c | 372 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-directory-private.h | 1 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-directory.c | 2 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file-private.h | 9 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file.c | 111 | ||||
-rw-r--r-- | libnautilus-private/nautilus-directory-async.c | 372 | ||||
-rw-r--r-- | libnautilus-private/nautilus-directory-private.h | 1 | ||||
-rw-r--r-- | libnautilus-private/nautilus-directory.c | 2 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-private.h | 9 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.c | 111 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.c | 8 | ||||
-rw-r--r-- | user-guide/C/Makefile.am | 1 |
14 files changed, 706 insertions, 373 deletions
@@ -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 |