5 #define TEST_FILE (SRCDIR "/Makefile.am")
6 char *test_file_buffer
;
8 static char async_read_buffer
[8192];
11 read_data (GObject
*source
, GAsyncResult
*result
, gpointer loop
)
13 GInputStream
*in
= G_INPUT_STREAM (source
);
17 nread
= g_input_stream_read_finish (in
, result
, &error
);
18 g_assert_no_error (error
);
20 g_assert_cmpint (nread
, >, 0);
21 g_assert_cmpint (nread
, <=, MIN(sizeof (async_read_buffer
), test_file_size
));
22 g_assert (memcmp (async_read_buffer
, test_file_buffer
, nread
) == 0);
24 g_main_loop_quit (loop
);
28 opened_for_read (GObject
*source
, GAsyncResult
*result
, gpointer loop
)
30 GFile
*file
= G_FILE (source
);
34 in
= g_file_read_finish (file
, result
, &error
);
35 g_assert_no_error (error
);
37 memset (async_read_buffer
, 0, sizeof (async_read_buffer
));
38 g_input_stream_read_async (G_INPUT_STREAM (in
),
39 async_read_buffer
, sizeof (async_read_buffer
),
40 G_PRIORITY_DEFAULT
, NULL
,
46 /* Test 1: Async I/O started in a thread with a thread-default context
47 * will stick to that thread, and will complete even if the default
48 * main loop is blocked. (NB: the last part would not be true if we
49 * were testing GFileMonitor!)
52 static gboolean
idle_start_test1_thread (gpointer loop
);
53 static gpointer
test1_thread (gpointer user_data
);
55 static gboolean test1_done
;
56 static GCond test1_cond
;
57 static GMutex test1_mutex
;
60 test_thread_independence (void)
64 loop
= g_main_loop_new (NULL
, FALSE
);
65 g_idle_add (idle_start_test1_thread
, loop
);
66 g_main_loop_run (loop
);
67 g_main_loop_unref (loop
);
71 idle_start_test1_thread (gpointer loop
)
75 gboolean io_completed
;
77 g_mutex_lock (&test1_mutex
);
78 thread
= g_thread_new ("test1", test1_thread
, NULL
);
80 time
= g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND
;
83 io_completed
= g_cond_wait_until (&test1_cond
, &test1_mutex
, time
);
84 g_assert (io_completed
);
86 g_thread_join (thread
);
88 g_mutex_unlock (&test1_mutex
);
89 g_main_loop_quit (loop
);
90 return G_SOURCE_REMOVE
;
94 test1_thread (gpointer user_data
)
96 GMainContext
*context
;
100 /* Wait for main thread to be waiting on test1_cond */
101 g_mutex_lock (&test1_mutex
);
103 context
= g_main_context_new ();
104 g_assert (g_main_context_get_thread_default () == NULL
);
105 g_main_context_push_thread_default (context
);
106 g_assert (g_main_context_get_thread_default () == context
);
108 file
= g_file_new_for_path (TEST_FILE
);
109 g_assert (g_file_supports_thread_contexts (file
));
111 loop
= g_main_loop_new (context
, FALSE
);
112 g_file_read_async (file
, G_PRIORITY_DEFAULT
, NULL
,
113 opened_for_read
, loop
);
114 g_object_unref (file
);
115 g_main_loop_run (loop
);
116 g_main_loop_unref (loop
);
119 g_cond_signal (&test1_cond
);
120 g_mutex_unlock (&test1_mutex
);
125 /* Test 2: If we push a thread-default context in the main thread, we
126 * can run async ops in that context without running the default
130 static gboolean
test2_fail (gpointer user_data
);
133 test_context_independence (void)
135 GMainContext
*context
;
138 guint default_timeout
;
139 GSource
*thread_default_timeout
;
141 context
= g_main_context_new ();
142 g_assert (g_main_context_get_thread_default () == NULL
);
143 g_main_context_push_thread_default (context
);
144 g_assert (g_main_context_get_thread_default () == context
);
146 file
= g_file_new_for_path (TEST_FILE
);
147 g_assert (g_file_supports_thread_contexts (file
));
149 /* Add a timeout to the main loop, to fail immediately if it gets run */
150 default_timeout
= g_timeout_add_full (G_PRIORITY_HIGH
, 0,
151 test2_fail
, NULL
, NULL
);
152 /* Add a timeout to the alternate loop, to fail if the I/O *doesn't* run */
153 thread_default_timeout
= g_timeout_source_new_seconds (2);
154 g_source_set_callback (thread_default_timeout
, test2_fail
, NULL
, NULL
);
155 g_source_attach (thread_default_timeout
, context
);
157 loop
= g_main_loop_new (context
, FALSE
);
158 g_file_read_async (file
, G_PRIORITY_DEFAULT
, NULL
,
159 opened_for_read
, loop
);
160 g_object_unref (file
);
161 g_main_loop_run (loop
);
162 g_main_loop_unref (loop
);
164 g_source_remove (default_timeout
);
165 g_source_destroy (thread_default_timeout
);
166 g_source_unref (thread_default_timeout
);
170 test2_fail (gpointer user_data
)
172 g_assert_not_reached ();
177 main (int argc
, char **argv
)
179 GError
*error
= NULL
;
182 g_test_init (&argc
, &argv
, NULL
);
184 g_file_get_contents (TEST_FILE
, &test_file_buffer
,
185 &test_file_size
, &error
);
186 g_assert_no_error (error
);
188 g_test_add_func ("/gio/contexts/thread-independence", test_thread_independence
);
189 g_test_add_func ("/gio/contexts/context-independence", test_context_independence
);