After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 712599 - Add an asynchronous version of gdk_pixbuf_get_file_info
Add an asynchronous version of gdk_pixbuf_get_file_info
Status: RESOLVED FIXED
Product: gdk-pixbuf
Classification: Platform
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gdk-pixbuf-maint
gdk-pixbuf-maint
Depends on:
Blocks: 708942
 
 
Reported: 2013-11-18 14:40 UTC by Debarshi Ray
Modified: 2014-08-31 15:45 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add an asynchronous version of gdk_pixbuf_get_file_info (6.66 KB, patch)
2013-11-18 14:44 UTC, Debarshi Ray
needs-work Details | Review
Add an asynchronous version of gdk_pixbuf_get_file_info (7.16 KB, patch)
2014-08-13 13:15 UTC, Debarshi Ray
committed Details | Review

Description Debarshi Ray 2013-11-18 14:40:30 UTC
Since gdk_pixbuf_get_file_info does I/O to parse the format and dimensions of a file, it would be nice to have an asynchronous version of it.
Comment 1 Debarshi Ray 2013-11-18 14:44:28 UTC
Created attachment 260126 [details] [review]
Add an asynchronous version of gdk_pixbuf_get_file_info
Comment 2 Bastien Nocera 2013-11-18 14:55:35 UTC
Review of attachment 260126 [details] [review]:

::: gdk-pixbuf/gdk-pixbuf-io.c
@@ +1981,3 @@
+        result = g_simple_async_result_new (NULL, callback, user_data, gdk_pixbuf_get_file_info_async);
+        g_simple_async_result_set_op_res_gpointer (result, data, (GDestroyNotify) get_file_info_data_async_data_free);
+        g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc) get_file_info_thread, G_PRIORITY_DEFAULT, cancellable);

No, because that's not cancellable. The async code should use async functions directly, passing the same cancellable to each one of the consecutive calls.
Comment 3 Debarshi Ray 2013-11-19 16:53:47 UTC
(In reply to comment #2)
> Review of attachment 260126 [details] [review]:
> 
> ::: gdk-pixbuf/gdk-pixbuf-io.c
> @@ +1981,3 @@
> +        result = g_simple_async_result_new (NULL, callback, user_data,
> gdk_pixbuf_get_file_info_async);
> +        g_simple_async_result_set_op_res_gpointer (result, data,
> (GDestroyNotify) get_file_info_data_async_data_free);
> +        g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc)
> get_file_info_thread, G_PRIORITY_DEFAULT, cancellable);
> 
> No, because that's not cancellable. The async code should use async functions
> directly, passing the same cancellable to each one of the consecutive calls.

That would result in having duplicate copies of the same code -- one for the older sync variant, one for the new cancellable async variant.

GTask (particularly see g_task_set_return_on_cancel) lets you add cancellability to uncancellable tasks. Our minimum GLib requirement is high enough to let us use GTask, so I think we should just do that.

From my reading of the code, I do not think g_simple_async_result_set_handle_cancellation lets you do such a thing. If it does, then great. Else we have GTask.

Other than that there are some mistakes in the usage of GSimpleAsyncResult in the existing code. eg., we use neither g_simple_async_result_set_check_cancellable nor g_simple_async_result_set_handle_cancellation. This is why I did not want to get into all these details in this patch, and just copied the existing format for implementing asynchronous operations. I plan to deal with these separately.
Comment 4 Debarshi Ray 2013-11-19 17:50:50 UTC
(In reply to comment #3)
> GTask (particularly see g_task_set_return_on_cancel) lets you add
> cancellability to uncancellable tasks. Our minimum GLib requirement is high
> enough to let us use GTask, so I think we should just do that.

I filed bug 712704 for the GTask porting.

> From my reading of the code, I do not think
> g_simple_async_result_set_handle_cancellation lets you do such a thing. If it
> does, then great. Else we have GTask.

I confirmed this from danw in #gtk+.
Comment 5 Bastien Nocera 2013-11-20 09:17:16 UTC
Given that we don't have any API for the async version yet, and the fact that gdk_pixbuf_get_file_info() uses fopen/fread, I'd rather have seen a _get_file_info_from_stream_async() and, yes, duplicate the 20 odd lines of code from the sync version so that even reads can be cancelled cleanly.
Comment 6 Debarshi Ray 2013-11-20 12:51:57 UTC
(In reply to comment #5)
> Given that we don't have any API for the async version yet, and the fact that
> gdk_pixbuf_get_file_info() uses fopen/fread, I'd rather have seen a
> _get_file_info_from_stream_async() and, yes, duplicate the 20 odd lines of code
> from the sync version so that even reads can be cancelled cleanly.

I guess what you are saying is to rewrite the sync version in terms of the async?
Comment 7 Bastien Nocera 2013-11-20 13:04:25 UTC
No, just that simply using GTask probably won't be enough to allow cancelling the fread calls.
Comment 8 Debarshi Ray 2013-11-20 16:16:51 UTC
(In reply to comment #7)
> No, just that simply using GTask probably won't be enough to allow cancelling
> the fread calls.

GTask will invoke the callback as soon as you cancel. The fopen/fread calls will continue to run in the thread, which will eventually be ignored. I am not too worried about that because we are not reading the whole file anyway, so the extra I/O overhead should be negligible.

If you want to cancel the fopen/fread, then we can write the async version with GIO operations, and then rewrite the sync version in terms of the async with a NULL cancellable.
Comment 9 Matthias Clasen 2014-08-12 22:51:11 UTC
Using GTask for this sounds good to me
Comment 10 Debarshi Ray 2014-08-13 13:15:12 UTC
Created attachment 283282 [details] [review]
Add an asynchronous version of gdk_pixbuf_get_file_info
Comment 11 Bastien Nocera 2014-08-14 11:50:01 UTC
(In reply to comment #9)
> Using GTask for this sounds good to me

The problem isn't using GTask, the problem is the lingering read() that doesn't actually get cancelled inside the thread.
Comment 12 Matthias Clasen 2014-08-31 15:44:56 UTC
Attachment 283282 [details] pushed as a70109b - Add an asynchronous version of gdk_pixbuf_get_file_info