diff options
| author | Victor Kareh <[email protected]> | 2026-07-30 14:47:41 -0400 |
|---|---|---|
| committer | Victor Kareh <[email protected]> | 2026-09-03 20:20:25 +0000 |
| commit | ac2c4c94eaa8f5fd5f77ff3ab107c38eeb663f59 (patch) | |
| tree | ae3c693b12f533ffdfc16bbeff1809fdc4c0df0e /libcaja-private | |
| parent | 12b8ce07a2213a1395d5078450ef0d0732ab5b9d (diff) | |
| download | caja-ac2c4c94eaa8f5fd5f77ff3ab107c38eeb663f59.tar.bz2 caja-ac2c4c94eaa8f5fd5f77ff3ab107c38eeb663f59.tar.xz | |
directory-async: Use 2 lists for call_when_ready callbacks
Use the words 'unsatisfied' and 'ready' instead of active and
inactive to better describe the two types.
Backport of https://gitlab.gnome.org/GNOME/nautilus/commit/156ff75c
Diffstat (limited to 'libcaja-private')
| -rw-r--r-- | libcaja-private/caja-directory-async.c | 200 | ||||
| -rw-r--r-- | libcaja-private/caja-directory-private.h | 11 |
2 files changed, 116 insertions, 95 deletions
diff --git a/libcaja-private/caja-directory-async.c b/libcaja-private/caja-directory-async.c index 84e17d4a..c100741a 100644 --- a/libcaja-private/caja-directory-async.c +++ b/libcaja-private/caja-directory-async.c @@ -161,11 +161,6 @@ typedef struct } callback; gpointer callback_data; Request request; - gboolean active; /* Set to FALSE when the callback is triggered and - * scheduled to be called at idle, its still kept - * in the list so we can kill it when the file - * goes away. - */ } ReadyCallback; typedef struct @@ -335,7 +330,7 @@ caja_directory_verify_request_counts (CajaDirectory *directory) { counters[i] = 0; } - for (l = directory->details->call_when_ready_list; l != NULL; l = l->next) + for (l = directory->details->call_when_ready_lists.unsatisfied; l != NULL; l = l->next) { ReadyCallback *callback = l->data; request_counter_add_request (counters, callback->request); @@ -1338,22 +1333,6 @@ ready_callback_key_compare (gconstpointer a, gconstpointer b) return 0; } -static int -ready_callback_key_compare_only_active (gconstpointer a, gconstpointer b) -{ - const ReadyCallback *callback_a; - - callback_a = a; - - /* Non active callbacks never match */ - if (!callback_a->active) - { - return -1; - } - - return ready_callback_key_compare (a, b); -} - static void ready_callback_call (CajaDirectory *directory, const ReadyCallback *callback) @@ -1406,7 +1385,6 @@ caja_directory_call_when_ready_internal (CajaDirectory *directory, g_assert (file != NULL || directory_callback != NULL); /* Construct a callback object. */ - callback.active = TRUE; callback.file = file; if (file == NULL) { @@ -1431,9 +1409,9 @@ caja_directory_call_when_ready_internal (CajaDirectory *directory, } /* Check if the callback is already there. */ - if (g_list_find_custom (directory->details->call_when_ready_list, - &callback, - ready_callback_key_compare_only_active) != NULL) + GList *unsatisfied_list = directory->details->call_when_ready_lists.unsatisfied; + + if (g_list_find_custom (unsatisfied_list, &callback, ready_callback_key_compare) != NULL) { if (file_callback != NULL && directory_callback != NULL) { @@ -1444,9 +1422,9 @@ caja_directory_call_when_ready_internal (CajaDirectory *directory, } /* Add the new callback to the list. */ - directory->details->call_when_ready_list = g_list_prepend - (directory->details->call_when_ready_list, - g_memdup (&callback, sizeof (callback))); + unsatisfied_list = g_list_prepend (unsatisfied_list, g_memdup (&callback, sizeof (callback))); + directory->details->call_when_ready_lists.unsatisfied = unsatisfied_list; + request_counter_add_request (directory->details->call_when_ready_counters, callback.request); @@ -1478,14 +1456,14 @@ caja_directory_check_if_ready_internal (CajaDirectory *directory, static void remove_callback_link_keep_data (CajaDirectory *directory, - GList *link) + GList *link, + gboolean ready) { - ReadyCallback *callback; - - callback = link->data; + ReadyCallback *callback = link->data; + GList **list = ready ? &directory->details->call_when_ready_lists.ready : + &directory->details->call_when_ready_lists.unsatisfied; - directory->details->call_when_ready_list = g_list_remove_link - (directory->details->call_when_ready_list, link); + *list = g_list_remove_link (*list, link); request_counter_remove_request (directory->details->call_when_ready_counters, callback->request); @@ -1494,15 +1472,52 @@ remove_callback_link_keep_data (CajaDirectory *directory, static void remove_callback_link (CajaDirectory *directory, - GList *link) + GList *link, + gboolean ready) { ReadyCallback *callback; callback = link->data; - remove_callback_link_keep_data (directory, link); + remove_callback_link_keep_data (directory, link, ready); g_free (callback); } +static void +remove_similar_callbacks (CajaDirectory *directory, + ReadyCallback *callback) +{ + GList *node; + + /* Remove all queued callback from the list (including ready). */ + do + { + node = g_list_find_custom (directory->details->call_when_ready_lists.ready, + callback, + ready_callback_key_compare); + if (node != NULL) + { + remove_callback_link (directory, node, TRUE); + + caja_directory_async_state_changed (directory); + } + } + while (node != NULL); + + do + { + node = g_list_find_custom (directory->details->call_when_ready_lists.unsatisfied, + callback, + ready_callback_key_compare); + if (node != NULL) + { + remove_callback_link (directory, node, FALSE); + + caja_directory_async_state_changed (directory); + } + } + while (node != NULL); +} + void caja_directory_cancel_callback_internal (CajaDirectory *directory, CajaFile *file, @@ -1511,7 +1526,6 @@ caja_directory_cancel_callback_internal (CajaDirectory *directory, gpointer callback_data) { ReadyCallback callback; - GList *node; if (directory == NULL) { @@ -1535,20 +1549,7 @@ caja_directory_cancel_callback_internal (CajaDirectory *directory, } callback.callback_data = callback_data; - /* Remove all queued callback from the list (including non-active). */ - do - { - node = g_list_find_custom (directory->details->call_when_ready_list, - &callback, - ready_callback_key_compare); - if (node != NULL) - { - remove_callback_link (directory, node); - - caja_directory_async_state_changed (directory); - } - } - while (node != NULL); + remove_similar_callbacks (directory, &callback); } static void @@ -1653,21 +1654,39 @@ caja_async_destroying_file (CajaFile *file) changed = FALSE; /* Check for callbacks. */ - for (node = directory->details->call_when_ready_list; node != NULL; node = next) + node = directory->details->call_when_ready_lists.unsatisfied; + + for (; node != NULL; node = next) { next = node->next; callback = node->data; - if (callback->file == file) + if (callback->file != file) { - /* Client should have cancelled callback. */ - if (callback->active) - { - g_warning ("destroyed file has call_when_ready pending"); - } - remove_callback_link (directory, node); - changed = TRUE; + continue; } + + /* Client should have cancelled callback. */ + g_warning ("destroyed file has call_when_ready pending"); + + remove_callback_link (directory, node, FALSE); + changed = TRUE; + } + + node = directory->details->call_when_ready_lists.ready; + + for (; node != NULL; node = next) + { + next = node->next; + callback = node->data; + + if (callback->file != file) + { + continue; + } + + remove_callback_link (directory, node, TRUE); + changed = TRUE; } /* Check for monitors. */ @@ -1993,7 +2012,7 @@ static gboolean call_ready_callbacks_at_idle (gpointer callback_data) { CajaDirectory *directory; - GList *node, *next; + GList *node; ReadyCallback *callback; directory = CAJA_DIRECTORY (callback_data); @@ -2002,27 +2021,13 @@ call_ready_callbacks_at_idle (gpointer callback_data) caja_directory_ref (directory); callback = NULL; - while (1) + /* Check if any callbacks are ready and call them if they are. */ + while ((node = directory->details->call_when_ready_lists.ready) != NULL) { - /* Check if any callbacks are non-active and call them if they are. */ - for (node = directory->details->call_when_ready_list; - node != NULL; node = next) - { - next = node->next; - callback = node->data; - if (!callback->active) - { - /* Non-active, remove and call */ - break; - } - } - if (node == NULL) - { - break; - } + callback = node->data; /* Callbacks are one-shots, so remove it now. */ - remove_callback_link_keep_data (directory, node); + remove_callback_link_keep_data (directory, node, TRUE); /* Call the callback. */ ready_callback_call (directory, callback); @@ -2046,7 +2051,7 @@ schedule_call_ready_callbacks (CajaDirectory *directory) } } -/* Marks all callbacks that are ready as non-active and +/* Moves all the callbacks that are ready and * calls them at idle time, unless they are removed * before then */ static gboolean @@ -2054,20 +2059,22 @@ call_ready_callbacks (CajaDirectory *directory) { gboolean found_any; GList *node, *next; - ReadyCallback *callback = NULL; + GList **unsatisfied_list, **ready_list; + + unsatisfied_list = &directory->details->call_when_ready_lists.unsatisfied; + ready_list = &directory->details->call_when_ready_lists.ready; found_any = FALSE; /* Check if any callbacks are satisifed and mark them for call them if they are. */ - for (node = directory->details->call_when_ready_list; - node != NULL; node = next) + for (node = *unsatisfied_list; node != NULL; node = next) { next = node->next; - callback = node->data; - if (callback->active && - request_is_satisfied (directory, callback->file, callback->request)) + ReadyCallback *callback = node->data; + if (request_is_satisfied (directory, callback->file, callback->request)) { - callback->active = FALSE; + *unsatisfied_list = g_list_delete_link (*unsatisfied_list, node); + *ready_list = g_list_prepend (*ready_list, callback); found_any = TRUE; } } @@ -2088,7 +2095,17 @@ caja_directory_has_active_request_for_file (CajaDirectory *directory, ReadyCallback *callback = NULL; Monitor *monitor = NULL; - for (node = directory->details->call_when_ready_list; + for (node = directory->details->call_when_ready_lists.unsatisfied; + node != NULL; node = node->next) + { + callback = node->data; + if (callback->file == file || + callback->file == NULL) + { + return TRUE; + } + } + for (node = directory->details->call_when_ready_lists.ready; node != NULL; node = node->next) { callback = node->data; @@ -2465,12 +2482,11 @@ is_needy (CajaFile *file, { ReadyCallback *callback = NULL; - for (node = directory->details->call_when_ready_list; + for (node = directory->details->call_when_ready_lists.unsatisfied; node != NULL; node = node->next) { callback = node->data; - if (callback->active && - REQUEST_WANTS_TYPE (callback->request, request_type_wanted)) + if (REQUEST_WANTS_TYPE (callback->request, request_type_wanted)) { if (callback->file == file) { diff --git a/libcaja-private/caja-directory-private.h b/libcaja-private/caja-directory-private.h index 51b18854..121ed639 100644 --- a/libcaja-private/caja-directory-private.h +++ b/libcaja-private/caja-directory-private.h @@ -89,10 +89,15 @@ struct _CajaDirectoryPrivate CajaFileQueue *low_priority_queue; CajaFileQueue *extension_queue; - /* These lists are going to be pretty short. If we think they - * are going to get big, we can use hash tables instead. + /* Callbacks are inserted into ready when the callback is triggered and + * scheduled to be called at idle. It's still kept in the list so we + * can kill it when the file goes away before being called. */ - GList *call_when_ready_list; + struct + { + GList *unsatisfied; + GList *ready; + } call_when_ready_lists; RequestCounter call_when_ready_counters; GList *monitor_list; RequestCounter monitor_counters; |
