# HG changeset patch # User nadvornik # Date 1212789009 0 # Node ID 6d65167764ea752db3ffd31eef1b6f4dba1de08b # Parent 43667426184062502861463b526cf3966c70ae9d realtime file monitor diff -r 436674261840 -r 6d65167764ea src/filedata.c --- a/src/filedata.c Fri Jun 06 20:59:03 2008 +0000 +++ b/src/filedata.c Fri Jun 06 21:50:09 2008 +0000 @@ -1443,17 +1443,28 @@ struct _NotifyData { FileDataNotifyFunc func; gpointer data; + NotifyPriority priority; }; static GList *notify_func_list = NULL; -gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data) +static gint file_data_notify_sort(gconstpointer a, gconstpointer b) +{ + NotifyData *nda = (NotifyData *)a; + NotifyData *ndb = (NotifyData *)b; + if (nda->priority < ndb->priority) return -1; + if (nda->priority > ndb->priority) return 1; + return 0; +} + +gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority) { NotifyData *nd = g_new(NotifyData, 1); nd->func = func; nd->data = data; - notify_func_list = g_list_prepend(notify_func_list, nd); - DEBUG_1("Notify func registered: %p\n", nd); + nd->priority = priority; + notify_func_list = g_list_insert_sorted(notify_func_list, nd, file_data_notify_sort); + DEBUG_1("Notify func registered: %p", nd); return TRUE; } @@ -1468,7 +1479,7 @@ { notify_func_list = g_list_delete_link(notify_func_list, work); g_free(nd); - DEBUG_1("Notify func unregistered: %p\n", nd); + DEBUG_1("Notify func unregistered: %p", nd); return TRUE; } work = work->next; @@ -1483,7 +1494,7 @@ while(work) { NotifyData *nd = (NotifyData *)work->data; - DEBUG_1("Notify func calling: %p %s\n", nd, fd->path); + DEBUG_1("Notify func calling: %p %s", nd, fd->path); nd->func(fd, nd->data); work = work->next; } @@ -1494,6 +1505,78 @@ } +static GHashTable *file_data_monitor_pool = NULL; +static gint realtime_monitor_id = -1; + +static void realtime_monitor_check_cb(gpointer key, gpointer value, gpointer data) +{ + FileData *fd = key; + struct stat st; + + stat_utf8(fd->path, &st); + + file_data_check_changed_files(fd, &st); + + DEBUG_1("monitor %s", fd->path); +} + +static gboolean realtime_monitor_cb(gpointer data) +{ + g_hash_table_foreach(file_data_monitor_pool, realtime_monitor_check_cb, NULL); + return TRUE; +} + +gint file_data_register_real_time_monitor(FileData *fd) +{ + gint count = 0; + + file_data_ref(fd); + + if (!file_data_monitor_pool) + file_data_monitor_pool = g_hash_table_new(g_direct_hash, g_direct_equal); + + count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd)); + + DEBUG_1("Register realtime %d %s", count, fd->path); + + count++; + g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count)); + + if (realtime_monitor_id == -1) + { + realtime_monitor_id = g_timeout_add(5000, realtime_monitor_cb, NULL); + } + return TRUE; +} + +gint file_data_unregister_real_time_monitor(FileData *fd) +{ + gint count; + g_assert(file_data_monitor_pool); + + count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd)); + + DEBUG_1("Unregister realtime %d %s", count, fd->path); + + g_assert(count > 0); + + count--; + + if (count == 0) + g_hash_table_remove(file_data_monitor_pool, fd); + else + g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count)); + + file_data_unref(fd); + + if (g_hash_table_size(file_data_monitor_pool) == 0) + { + g_source_remove(realtime_monitor_id); + realtime_monitor_id = -1; + return FALSE; + } + return TRUE; +} diff -r 436674261840 -r 6d65167764ea src/filedata.h --- a/src/filedata.h Fri Jun 06 20:59:03 2008 +0000 +++ b/src/filedata.h Fri Jun 06 21:50:09 2008 +0000 @@ -78,7 +78,11 @@ void file_data_sc_free_ci_list(GList *fd_list); typedef void (*FileDataNotifyFunc)(FileData *fd, gpointer data); -gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data); +gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority); gint file_data_unregister_notify_func(FileDataNotifyFunc func, gpointer data); void file_data_send_notification(FileData *fd); + +gint file_data_register_real_time_monitor(FileData *fd); +gint file_data_unregister_real_time_monitor(FileData *fd); + #endif diff -r 436674261840 -r 6d65167764ea src/layout.c --- a/src/layout.c Fri Jun 06 20:59:03 2008 +0000 +++ b/src/layout.c Fri Jun 06 21:50:09 2008 +0000 @@ -937,8 +937,13 @@ if (isdir(fd->path)) { - file_data_unref(lw->dir_fd); + if (lw->dir_fd) + { + file_data_unregister_real_time_monitor(lw->dir_fd); + file_data_unref(lw->dir_fd); + } lw->dir_fd = file_data_ref(fd); + file_data_register_real_time_monitor(fd); } else { @@ -951,8 +956,13 @@ } else if (isdir(base)) { - file_data_unref(lw->dir_fd); + if (lw->dir_fd) + { + file_data_unregister_real_time_monitor(lw->dir_fd); + file_data_unref(lw->dir_fd); + } lw->dir_fd = file_data_new_simple(base); + file_data_register_real_time_monitor(lw->dir_fd); g_free(base); } else @@ -1608,6 +1618,7 @@ layout_image_full_screen_stop(lw); dir_fd = lw->dir_fd; + file_data_unregister_real_time_monitor(lw->dir_fd); lw->dir_fd = NULL; lw->image = NULL; lw->utility_box = NULL; @@ -1826,16 +1837,16 @@ layout_window_list = g_list_remove(layout_window_list, lw); - if (lw->last_time_id != -1) - { - g_source_remove(lw->last_time_id); - } - + layout_bars_close(lw); gtk_widget_destroy(lw->window); - file_data_unref(lw->dir_fd); + if (lw->dir_fd) + { + file_data_unregister_real_time_monitor(lw->dir_fd); + file_data_unref(lw->dir_fd); + } g_free(lw); } @@ -1979,7 +1990,7 @@ /* set up the time stat timeout */ lw->last_version = 0; - lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw); +// lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw); if (geometry) { diff -r 436674261840 -r 6d65167764ea src/typedefs.h --- a/src/typedefs.h Fri Jun 06 20:59:03 2008 +0000 +++ b/src/typedefs.h Fri Jun 06 21:50:09 2008 +0000 @@ -131,6 +131,13 @@ SS_ERR_OTHER, } SecureSaveErrno; +typedef enum { + NOTIFY_PRIORITY_HIGH = 0, + NOTIFY_PRIORITY_MEDIUM, + NOTIFY_PRIORITY_LOW +} NotifyPriority; + + #define MAX_SPLIT_IMAGES 4 @@ -539,7 +546,6 @@ /* directory update check */ - gint last_time_id; gint last_version; /* misc */ diff -r 436674261840 -r 6d65167764ea src/view_file_icon.c --- a/src/view_file_icon.c Fri Jun 06 20:59:03 2008 +0000 +++ b/src/view_file_icon.c Fri Jun 06 21:50:09 2008 +0000 @@ -2301,7 +2301,7 @@ /* force VFICON_INFO(vf, columns) to be at least 1 (sane) - this will be corrected in the size_cb */ vficon_populate_at_new_size(vf, 1, 1, FALSE); - file_data_register_notify_func(vficon_notify_cb, vf); + file_data_register_notify_func(vficon_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); return vf; } diff -r 436674261840 -r 6d65167764ea src/view_file_list.c --- a/src/view_file_list.c Fri Jun 06 20:59:03 2008 +0000 +++ b/src/view_file_list.c Fri Jun 06 21:50:09 2008 +0000 @@ -1463,7 +1463,7 @@ file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */ file_data_increment_version(fd); - file_data_register_notify_func(vflist_notify_cb, vf); + file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); gtk_tree_store_set(GTK_TREE_STORE(store), &iter, FILE_COLUMN_MARKS + n, fd->marks[n], -1); @@ -1570,7 +1570,7 @@ ret = filelist_read(vf->dir_fd, &vf->list, NULL); - file_data_register_notify_func(vflist_notify_cb, vf); + file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); DEBUG_1("%s vflist_refresh: sort", get_exec_time()); vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); @@ -1711,7 +1711,7 @@ fd->marks[col_idx - FILE_COLUMN_MARKS] = mark; file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */ file_data_increment_version(fd); - file_data_register_notify_func(vflist_notify_cb, vf); + file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); gtk_tree_store_set(store, &iter, col_idx, mark, -1); gtk_tree_path_free(path); @@ -1832,7 +1832,7 @@ vflist_listview_add_column(vf, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE, FALSE); vflist_listview_add_column(vf, FILE_COLUMN_DATE, _("Date"), FALSE, TRUE, FALSE); - file_data_register_notify_func(vflist_notify_cb, vf); + file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); return vf; }