2 * Copyright © 2014 Canonical Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * Authors: Ryan Lortie <desrt@desrt.ca>
23 static gboolean expected_read_success
;
24 static guint expected_read
;
25 static gboolean got_read_done
;
28 read_done (GObject
*source
,
35 success
= g_input_stream_read_all_finish (G_INPUT_STREAM (source
), result
, &read
, NULL
);
36 g_assert_cmpint (expected_read_success
, ==, success
);
37 g_assert_cmpint (expected_read
, ==, read
);
42 wait_for_read (gboolean success
,
45 g_assert (!got_read_done
);
46 expected_read_success
= success
;
49 while (!got_read_done
)
50 g_main_context_iteration (NULL
, TRUE
);
52 got_read_done
= FALSE
;
55 static gboolean expected_write_success
;
56 static guint expected_written
;
57 static gboolean got_write_done
;
60 write_done (GObject
*source
,
67 success
= g_output_stream_write_all_finish (G_OUTPUT_STREAM (source
), result
, &written
, NULL
);
68 g_assert_cmpint (expected_write_success
, ==, success
);
69 g_assert_cmpint (expected_written
, ==, written
);
70 got_write_done
= TRUE
;
74 wait_for_write (gboolean success
,
77 g_assert (!got_write_done
);
78 expected_write_success
= success
;
79 expected_written
= written
;
81 while (!got_write_done
)
82 g_main_context_iteration (NULL
, TRUE
);
84 got_write_done
= FALSE
;
88 test_write_all_async_memory (void)
93 ms
= g_memory_output_stream_new (b
, sizeof b
, NULL
, NULL
);
95 g_output_stream_write_all_async (ms
, "0123456789", 10, 0, NULL
, write_done
, NULL
);
96 wait_for_write (TRUE
, 10);
98 g_output_stream_write_all_async (ms
, "0123456789", 10, 0, NULL
, write_done
, NULL
);
99 wait_for_write (TRUE
, 10);
101 /* this will trigger an out-of-space error, but we will see the
104 g_output_stream_write_all_async (ms
, "0123456789", 10, 0, NULL
, write_done
, NULL
);
105 wait_for_write (FALSE
, 4);
107 /* and still an error, but no further bytes written */
108 g_output_stream_write_all_async (ms
, "0123456789", 10, 0, NULL
, write_done
, NULL
);
109 wait_for_write (FALSE
, 0);
111 g_assert (!memcmp (b
, "012345678901234567890123", 24));
117 test_read_all_async_memory (void)
120 gchar b
[24] = "0123456789ABCDEFGHIJ!@#$";
123 ms
= g_memory_input_stream_new_from_data (b
, sizeof b
, NULL
);
125 g_input_stream_read_all_async (ms
, buf
, 10, 0, NULL
, read_done
, NULL
);
126 wait_for_read (TRUE
, 10);
127 g_assert (!memcmp (buf
, "0123456789", 10));
129 g_input_stream_read_all_async (ms
, buf
, 10, 0, NULL
, read_done
, NULL
);
130 wait_for_read (TRUE
, 10);
131 g_assert (!memcmp (buf
, "ABCDEFGHIJ", 10));
133 /* partial read... */
134 g_input_stream_read_all_async (ms
, buf
, 10, 0, NULL
, read_done
, NULL
);
135 wait_for_read (TRUE
, 4);
136 g_assert (!memcmp (buf
, "!@#$", 4));
139 g_input_stream_read_all_async (ms
, buf
, 10, 0, NULL
, read_done
, NULL
);
140 wait_for_read (TRUE
, 0);
147 #include <sys/types.h>
148 #include <sys/socket.h>
149 #include <gio/gunixinputstream.h>
150 #include <gio/gunixoutputstream.h>
153 test_read_write_all_async_pipe (void)
155 GCancellable
*cancellable
;
156 GError
*error
= NULL
;
161 gchar wbuf
[100] = { 0, };
168 s
= socketpair (AF_UNIX
, SOCK_STREAM
, 0, sv
);
171 out
= g_unix_output_stream_new (sv
[0], TRUE
);
172 in
= g_unix_input_stream_new (sv
[1], TRUE
);
175 /* Try to fill up the buffer */
177 while (g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (out
)))
179 s
= g_output_stream_write (out
, wbuf
, sizeof wbuf
, NULL
, &error
);
180 g_assert_no_error (error
);
185 /* Now start a blocking write_all; nothing should happen. */
186 cancellable
= g_cancellable_new ();
187 g_output_stream_write_all_async (out
, "0123456789", 10, 0, cancellable
, write_done
, NULL
);
188 while (g_main_context_iteration (NULL
, FALSE
))
190 g_assert (!got_write_done
);
192 /* Cancel that to make sure it works */
193 g_cancellable_cancel (cancellable
);
194 g_object_unref (cancellable
);
195 wait_for_write (FALSE
, 0);
198 g_output_stream_write_all_async (out
, "0123456789", 10, 0, NULL
, write_done
, NULL
);
199 while (g_main_context_iteration (NULL
, FALSE
))
201 g_assert (!got_write_done
);
203 /* Now drain as much as we originally put in the buffer to make it
204 * block -- this will unblock the writer.
208 s
= g_input_stream_read (in
, rbuf
, MIN (sizeof wbuf
, in_flight
), NULL
, &error
);
209 g_assert_no_error (error
);
214 /* That will have caused some writing to start happening. Do a
215 * read_all as well, for more bytes than was written.
217 g_input_stream_read_all_async (in
, rbuf
, sizeof rbuf
, 0, NULL
, read_done
, NULL
);
219 /* The write is surely finished by now */
220 wait_for_write (TRUE
, 10);
221 /* ...but the read will not yet be satisfied */
222 g_assert (!got_read_done
);
224 /* Feed the read more than it asked for; this really should not block
225 * since the buffer is so small...
227 g_output_stream_write_all (out
, wbuf
, sizeof wbuf
, 0, NULL
, &error
);
228 g_assert_no_error (error
);
230 /* Read will have finished now */
231 wait_for_read (TRUE
, sizeof rbuf
);
233 /* Close the writer end to make an EOF condition */
234 g_output_stream_close (out
, NULL
, NULL
);
236 /* ... and we should have exactly 10 extra bytes left in the buffer */
237 g_input_stream_read_all_async (in
, rbuf
, sizeof rbuf
, 0, NULL
, read_done
, NULL
);
238 wait_for_read (TRUE
, 10);
240 g_object_unref (out
);
249 g_test_init (&argc
, &argv
, NULL
);
251 g_test_add_func ("/stream/read_all_async/memory", test_read_all_async_memory
);
252 g_test_add_func ("/stream/write_all_async/memory", test_write_all_async_memory
);
254 g_test_add_func ("/stream/read_write_all_async/pipe", test_read_write_all_async_pipe
);