mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-28 16:36:14 +01:00
Merge branch 'wip/carlosg/cancelled-splice' into 'master'
Fix splice behavior on cancellation See merge request GNOME/glib!1631
This commit is contained in:
commit
e5c119ea41
@ -2643,6 +2643,8 @@ g_output_stream_real_writev_finish (GOutputStream *stream,
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
GInputStream *source;
|
GInputStream *source;
|
||||||
GOutputStreamSpliceFlags flags;
|
GOutputStreamSpliceFlags flags;
|
||||||
|
guint istream_closed : 1;
|
||||||
|
guint ostream_closed : 1;
|
||||||
gssize n_read;
|
gssize n_read;
|
||||||
gssize n_written;
|
gssize n_written;
|
||||||
gsize bytes_copied;
|
gsize bytes_copied;
|
||||||
@ -2665,11 +2667,11 @@ real_splice_async_complete_cb (GTask *task)
|
|||||||
SpliceData *op = g_task_get_task_data (task);
|
SpliceData *op = g_task_get_task_data (task);
|
||||||
|
|
||||||
if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE &&
|
if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE &&
|
||||||
!g_input_stream_is_closed (op->source))
|
!op->istream_closed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET &&
|
if (op->flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET &&
|
||||||
!g_output_stream_is_closed (g_task_get_source_object (task)))
|
!op->ostream_closed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (op->error != NULL)
|
if (op->error != NULL)
|
||||||
@ -2691,8 +2693,10 @@ real_splice_async_close_input_cb (GObject *source,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GTask *task = user_data;
|
GTask *task = user_data;
|
||||||
|
SpliceData *op = g_task_get_task_data (task);
|
||||||
|
|
||||||
g_input_stream_close_finish (G_INPUT_STREAM (source), res, NULL);
|
g_input_stream_close_finish (G_INPUT_STREAM (source), res, NULL);
|
||||||
|
op->istream_closed = TRUE;
|
||||||
|
|
||||||
real_splice_async_complete_cb (task);
|
real_splice_async_complete_cb (task);
|
||||||
}
|
}
|
||||||
@ -2707,6 +2711,7 @@ real_splice_async_close_output_cb (GObject *source,
|
|||||||
GError **error = (op->error == NULL) ? &op->error : NULL;
|
GError **error = (op->error == NULL) ? &op->error : NULL;
|
||||||
|
|
||||||
g_output_stream_internal_close_finish (G_OUTPUT_STREAM (source), res, error);
|
g_output_stream_internal_close_finish (G_OUTPUT_STREAM (source), res, error);
|
||||||
|
op->ostream_closed = TRUE;
|
||||||
|
|
||||||
real_splice_async_complete_cb (task);
|
real_splice_async_complete_cb (task);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ typedef enum
|
|||||||
TEST_THREADED_NONE = 0,
|
TEST_THREADED_NONE = 0,
|
||||||
TEST_THREADED_ISTREAM = 1,
|
TEST_THREADED_ISTREAM = 1,
|
||||||
TEST_THREADED_OSTREAM = 2,
|
TEST_THREADED_OSTREAM = 2,
|
||||||
|
TEST_CANCEL = 4,
|
||||||
TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM,
|
TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM,
|
||||||
} TestThreadedFlags;
|
} TestThreadedFlags;
|
||||||
|
|
||||||
@ -58,6 +59,14 @@ test_copy_chunks_splice_cb (GObject *source,
|
|||||||
|
|
||||||
bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
|
bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
|
||||||
res, &error);
|
res, &error);
|
||||||
|
|
||||||
|
if (data->flags & TEST_CANCEL)
|
||||||
|
{
|
||||||
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||||
|
g_main_loop_quit (data->main_loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert_cmpint (bytes_spliced, ==, strlen (data->data));
|
g_assert_cmpint (bytes_spliced, ==, strlen (data->data));
|
||||||
|
|
||||||
@ -100,11 +109,18 @@ test_copy_chunks_start (TestThreadedFlags flags)
|
|||||||
{
|
{
|
||||||
TestCopyChunksData data;
|
TestCopyChunksData data;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
GCancellable *cancellable = NULL;
|
||||||
|
|
||||||
data.main_loop = g_main_loop_new (NULL, FALSE);
|
data.main_loop = g_main_loop_new (NULL, FALSE);
|
||||||
data.data = "abcdefghijklmnopqrstuvwxyz";
|
data.data = "abcdefghijklmnopqrstuvwxyz";
|
||||||
data.flags = flags;
|
data.flags = flags;
|
||||||
|
|
||||||
|
if (data.flags & TEST_CANCEL)
|
||||||
|
{
|
||||||
|
cancellable = g_cancellable_new ();
|
||||||
|
g_cancellable_cancel (cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.flags & TEST_THREADED_ISTREAM)
|
if (data.flags & TEST_THREADED_ISTREAM)
|
||||||
{
|
{
|
||||||
GFile *file;
|
GFile *file;
|
||||||
@ -150,7 +166,7 @@ test_copy_chunks_start (TestThreadedFlags flags)
|
|||||||
g_output_stream_splice_async (data.ostream, data.istream,
|
g_output_stream_splice_async (data.ostream, data.istream,
|
||||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
|
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
|
||||||
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||||
G_PRIORITY_DEFAULT, NULL,
|
G_PRIORITY_DEFAULT, cancellable,
|
||||||
test_copy_chunks_splice_cb, &data);
|
test_copy_chunks_splice_cb, &data);
|
||||||
|
|
||||||
/* We do not hold a ref in data struct, this is to make sure the operation
|
/* We do not hold a ref in data struct, this is to make sure the operation
|
||||||
@ -158,6 +174,7 @@ test_copy_chunks_start (TestThreadedFlags flags)
|
|||||||
*/
|
*/
|
||||||
g_object_unref (data.istream);
|
g_object_unref (data.istream);
|
||||||
g_object_unref (data.ostream);
|
g_object_unref (data.ostream);
|
||||||
|
g_clear_object (&cancellable);
|
||||||
|
|
||||||
g_main_loop_run (data.main_loop);
|
g_main_loop_run (data.main_loop);
|
||||||
g_main_loop_unref (data.main_loop);
|
g_main_loop_unref (data.main_loop);
|
||||||
@ -187,6 +204,12 @@ test_copy_chunks_threaded (void)
|
|||||||
test_copy_chunks_start (TEST_THREADED_BOTH);
|
test_copy_chunks_start (TEST_THREADED_BOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_cancelled (void)
|
||||||
|
{
|
||||||
|
test_copy_chunks_start (TEST_THREADED_NONE | TEST_CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@ -200,6 +223,8 @@ main (int argc,
|
|||||||
test_copy_chunks_threaded_output);
|
test_copy_chunks_threaded_output);
|
||||||
g_test_add_func ("/async-splice/copy-chunks-threaded",
|
g_test_add_func ("/async-splice/copy-chunks-threaded",
|
||||||
test_copy_chunks_threaded);
|
test_copy_chunks_threaded);
|
||||||
|
g_test_add_func ("/async-splice/cancelled",
|
||||||
|
test_cancelled);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user