gboolean on_thumbnail_idle( VFSThumbnailLoader* loader ) { VFSFileInfo* file; /* g_debug( "ENTER ON_THUMBNAIL_IDLE" ); */ vfs_async_task_lock( loader->task ); while( ( file = (VFSFileInfo*)g_queue_pop_head(loader->update_queue) ) ) { GDK_THREADS_ENTER(); vfs_dir_emit_thumbnail_loaded( loader->dir, file ); vfs_file_info_unref( file ); GDK_THREADS_LEAVE(); } loader->idle_handler = 0; vfs_async_task_unlock( loader->task ); if( vfs_async_task_is_finished( loader->task ) ) { /* g_debug( "FREE LOADER IN IDLE HANDLER" ); */ loader->dir->thumbnail_loader = NULL; vfs_thumbnail_loader_free(loader); } /* g_debug( "LEAVE ON_THUMBNAIL_IDLE" ); */ return FALSE; }
void vfs_thumbnail_loader_cancel_all_requests( VFSDir* dir, gboolean is_big ) { GList* l; VFSThumbnailLoader* loader; ThumbnailRequest* req; if( G_UNLIKELY( (loader=dir->thumbnail_loader) ) ) { vfs_async_task_lock( loader->task ); /* g_debug( "TRY TO CANCEL REQUESTS!!" ); */ for( l = loader->queue->head; l; ) { req = (ThumbnailRequest*)l->data; --req->n_requests[ is_big ? LOAD_BIG_THUMBNAIL : LOAD_SMALL_THUMBNAIL ]; if( req->n_requests[0] <= 0 && req->n_requests[1] <= 0 ) /* nobody needs this */ { GList* next = l->next; g_queue_delete_link( loader->queue, l ); l = next; } else l = l->next; } if( g_queue_get_length( loader->queue ) == 0 ) { /* g_debug( "FREE LOADER IN vfs_thumbnail_loader_cancel_all_requests!" ); */ vfs_async_task_unlock( loader->task ); loader->dir->thumbnail_loader = NULL; /* FIXME: added idle_handler = 0 to prevent idle_handler being * removed in vfs_thumbnail_loader_free - BUT causes a segfault * in vfs_async_task_lock ?? * If source is removed here or in vfs_thumbnail_loader_free * it causes a "GLib-CRITICAL **: Source ID N was not found when * attempting to remove it" warning. Such a source ID is always * the one added in thumbnail_loader_thread at the "add2" comment. */ //loader->idle_handler = 0; vfs_thumbnail_loader_free( loader ); return; } vfs_async_task_unlock( loader->task ); } }
void vfs_thumbnail_loader_cancel_all_requests( VFSDir* dir, gboolean is_big ) { GList* l; VFSThumbnailLoader* loader; ThumbnailRequest* req; if( G_UNLIKELY( (loader=dir->thumbnail_loader) ) ) { vfs_async_task_lock( loader->task ); /* g_debug( "TRY TO CANCEL REQUESTS!!" ); */ for( l = loader->queue->head; l; ) { req = (ThumbnailRequest*)l->data; --req->n_requests[ is_big ? LOAD_BIG_THUMBNAIL : LOAD_SMALL_THUMBNAIL ]; if( req->n_requests[0] <= 0 && req->n_requests[1] <= 0 ) /* nobody needs this */ { GList* next = l->next; g_queue_delete_link( loader->queue, l ); l = next; } else l = l->next; } if( g_queue_get_length( loader->queue ) == 0 ) { /* g_debug( "FREE LOADER IN vfs_thumbnail_loader_cancel_all_requests!" ); */ vfs_async_task_unlock( loader->task ); loader->dir->thumbnail_loader = NULL; vfs_thumbnail_loader_free( loader ); return; } vfs_async_task_unlock( loader->task ); } }
void vfs_dir_finalize( GObject *obj ) { VFSDir * dir = VFS_DIR( obj ); do{} while( g_source_remove_by_user_data( dir ) ); if( G_UNLIKELY( dir->task ) ) { g_signal_handlers_disconnect_by_func( dir->task, on_list_task_finished, dir ); /* FIXME: should we generate a "file-list" signal to indicate the dir loading was cancelled? */ //printf("spacefm: vfs_dir_finalize -> vfs_async_task_cancel\n"); vfs_async_task_cancel( dir->task ); g_object_unref( dir->task ); dir->task = NULL; } if ( dir->monitor ) { vfs_file_monitor_remove( dir->monitor, vfs_dir_monitor_callback, dir ); } if ( dir->path ) { if( G_LIKELY( dir_hash ) ) { g_hash_table_remove( dir_hash, dir->path ); /* There is no VFSDir instance */ if ( 0 == g_hash_table_size( dir_hash ) ) { g_hash_table_destroy( dir_hash ); dir_hash = NULL; vfs_mime_type_remove_reload_cb( mime_cb ); mime_cb = NULL; if( change_notify_timeout ) { g_source_remove( change_notify_timeout ); change_notify_timeout = 0; } g_signal_handler_disconnect( gtk_icon_theme_get_default(), theme_change_notify ); theme_change_notify = 0; } } g_free( dir->path ); g_free( dir->disp_path ); dir->path = dir->disp_path = NULL; } /* g_debug( "dir->thumbnail_loader: %p", dir->thumbnail_loader ); */ if( G_UNLIKELY( dir->thumbnail_loader ) ) { /* g_debug( "FREE THUMBNAIL LOADER IN VFSDIR" ); */ vfs_thumbnail_loader_free( dir->thumbnail_loader ); dir->thumbnail_loader = NULL; } if ( dir->file_list ) { g_list_foreach( dir->file_list, ( GFunc ) vfs_file_info_unref, NULL ); g_list_free( dir->file_list ); dir->file_list = NULL; dir->n_files = 0; } if( dir->changed_files ) { g_slist_foreach( dir->changed_files, (GFunc)vfs_file_info_unref, NULL ); g_slist_free( dir->changed_files ); dir->changed_files = NULL; } if( dir->created_files ) { g_slist_foreach( dir->created_files, (GFunc)g_free, NULL ); g_slist_free( dir->created_files ); dir->created_files = NULL; } g_mutex_free( dir->mutex ); G_OBJECT_CLASS( parent_class ) ->finalize( obj ); }