mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 15:56:23 +01:00
Bug 562452 - Ensure we return G_IO_ERROR_CANCELLED if cancelling
2008-12-10 Alexander Larsson <alexl@redhat.com> Bug 562452 - Ensure we return G_IO_ERROR_CANCELLED if cancelling g_simple_async_result_run_in_thread * gsimpleasyncresult.c: Make g_simple_async_result_run_in_thread check cancellation before calling out to the user in the callback. This means we guarantee reporting cancels of async operations from the main threads, which is probably more in line with what users expect. Note that there are still no such guarantees for cancelling sync operations or cancelling async operation from outside the main thread. Furthermore, the exact behaviour of async implementations not using run_in_thread may differ. svn path=/trunk/; revision=7740
This commit is contained in:
parent
b7c11505f9
commit
3b4ad625b9
@ -1,3 +1,19 @@
|
||||
2008-12-10 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
Bug 562452 - Ensure we return G_IO_ERROR_CANCELLED if cancelling
|
||||
g_simple_async_result_run_in_thread
|
||||
|
||||
* gsimpleasyncresult.c:
|
||||
Make g_simple_async_result_run_in_thread check cancellation before
|
||||
calling out to the user in the callback. This means we guarantee
|
||||
reporting cancels of async operations from the main threads, which
|
||||
is probably more in line with what users expect.
|
||||
|
||||
Note that there are still no such guarantees for cancelling sync
|
||||
operations or cancelling async operation from outside the main
|
||||
thread. Furthermore, the exact behaviour of async implementations
|
||||
not using run_in_thread may differ.
|
||||
|
||||
2008-12-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
Bug 515777 - incorrect date&time on copy
|
||||
|
@ -83,7 +83,9 @@
|
||||
*
|
||||
* An asynchronous operation can be made to ignore a cancellation event by
|
||||
* calling g_simple_async_result_set_handle_cancellation() with a
|
||||
* #GSimpleAsyncResult for the operation and %FALSE.
|
||||
* #GSimpleAsyncResult for the operation and %FALSE. This is useful for
|
||||
* operations that are dangerous to cancel, such as close (which would
|
||||
* cause a leak if cancelled before being run).
|
||||
*
|
||||
* GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop,
|
||||
* or it can use #GThread<!-- -->s if available.
|
||||
@ -464,6 +466,8 @@ g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
|
||||
g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
|
||||
g_return_if_fail (error != NULL);
|
||||
|
||||
if (simple->error)
|
||||
g_error_free (simple->error);
|
||||
simple->error = g_error_copy (error);
|
||||
simple->failed = TRUE;
|
||||
}
|
||||
@ -507,6 +511,8 @@ g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
|
||||
g_return_if_fail (domain != 0);
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
if (simple->error)
|
||||
g_error_free (simple->error);
|
||||
simple->error = _g_error_new_valist (domain, code, format, args);
|
||||
simple->failed = TRUE;
|
||||
}
|
||||
@ -544,6 +550,9 @@ g_simple_async_result_set_error (GSimpleAsyncResult *simple,
|
||||
* @simple: a #GSimpleAsyncResult.
|
||||
*
|
||||
* Completes an asynchronous I/O job.
|
||||
* Must be called in the main thread, as it invokes the callback that
|
||||
* should be called in the main thread. If you are in a different thread
|
||||
* use g_simple_async_result_complete_in_idle().
|
||||
**/
|
||||
void
|
||||
g_simple_async_result_complete (GSimpleAsyncResult *simple)
|
||||
@ -593,9 +602,36 @@ g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
|
||||
|
||||
typedef struct {
|
||||
GSimpleAsyncResult *simple;
|
||||
GCancellable *cancellable;
|
||||
GSimpleAsyncThreadFunc func;
|
||||
} RunInThreadData;
|
||||
|
||||
|
||||
static gboolean
|
||||
complete_in_idle_cb_for_thread (gpointer _data)
|
||||
{
|
||||
RunInThreadData *data = _data;
|
||||
GSimpleAsyncResult *simple;
|
||||
|
||||
simple = data->simple;
|
||||
|
||||
if (simple->handle_cancellation &&
|
||||
g_cancellable_is_cancelled (data->cancellable))
|
||||
g_simple_async_result_set_error (simple,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED,
|
||||
"%s", _("Operation was cancelled"));
|
||||
|
||||
g_simple_async_result_complete (simple);
|
||||
|
||||
if (data->cancellable)
|
||||
g_object_unref (data->cancellable);
|
||||
g_object_unref (data->simple);
|
||||
g_free (data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
run_in_thread (GIOSchedulerJob *job,
|
||||
GCancellable *c,
|
||||
@ -603,6 +639,8 @@ run_in_thread (GIOSchedulerJob *job,
|
||||
{
|
||||
RunInThreadData *data = _data;
|
||||
GSimpleAsyncResult *simple = data->simple;
|
||||
GSource *source;
|
||||
guint id;
|
||||
|
||||
if (simple->handle_cancellation &&
|
||||
g_cancellable_is_cancelled (c))
|
||||
@ -615,9 +653,12 @@ run_in_thread (GIOSchedulerJob *job,
|
||||
simple->source_object,
|
||||
c);
|
||||
|
||||
g_simple_async_result_complete_in_idle (data->simple);
|
||||
g_object_unref (data->simple);
|
||||
g_free (data);
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_priority (source, G_PRIORITY_DEFAULT);
|
||||
g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
|
||||
|
||||
id = g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -645,6 +686,9 @@ g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
|
||||
data = g_new (RunInThreadData, 1);
|
||||
data->func = func;
|
||||
data->simple = g_object_ref (simple);
|
||||
data->cancellable = cancellable;
|
||||
if (cancellable)
|
||||
g_object_ref (cancellable);
|
||||
g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user