diff -r e4d67989cc36 -r 47c74d1534e1 glib/tests/asyncqueue-test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glib/tests/asyncqueue-test.c Fri Apr 16 16:46:38 2010 +0300 @@ -0,0 +1,223 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + +#include +#include + +#include + +#define DEBUG_MSG(args) +/* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */ +#define PRINT_MSG(args) +/* #define PRINT_MSG(args) g_print args ; g_print ("\n"); */ + +#define MAX_THREADS 50 +#define MAX_SORTS 5 /* only applies if + ASYC_QUEUE_DO_SORT is set to 1 */ +#define MAX_TIME 20 /* seconds */ +#define MIN_TIME 5 /* seconds */ + +#define SORT_QUEUE_AFTER 1 +#define SORT_QUEUE_ON_PUSH 1 /* if this is done, the + SORT_QUEUE_AFTER is ignored */ +#define QUIT_WHEN_DONE 1 + + +#if SORT_QUEUE_ON_PUSH == 1 +# undef SORT_QUEUE_AFTER +# define SORT_QUEUE_AFTER 0 +#endif + +#ifdef __SYMBIAN32__ +#include "mrt2_glib2_test.h" +#endif /*__SYMBIAN32__*/ + + +static GMainLoop *main_loop = NULL; +static GThreadPool *thread_pool = NULL; +static GAsyncQueue *async_queue = NULL; + + +static gint +sort_compare (gconstpointer p1, gconstpointer p2, gpointer user_data) +{ + gint32 id1; + gint32 id2; + + id1 = GPOINTER_TO_INT (p1); + id2 = GPOINTER_TO_INT (p2); + + DEBUG_MSG (("comparing #1:%d and #2:%d, returning %d", + id1, id2, (id1 > id2 ? +1 : id1 == id2 ? 0 : -1))); + + return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); +} + +static gboolean +sort_queue (gpointer user_data) +{ + static gint sorts = 0; + static gpointer last_p = NULL; + gpointer p; + gboolean can_quit = FALSE; + gint sort_multiplier; + gint len; + gint i; + + sort_multiplier = GPOINTER_TO_INT (user_data); + + if (SORT_QUEUE_AFTER) { + PRINT_MSG (("sorting async queue...")); + g_async_queue_sort (async_queue, sort_compare, NULL); + + sorts++; + + if (sorts >= sort_multiplier) { + can_quit = TRUE; + } + + g_async_queue_sort (async_queue, sort_compare, NULL); + len = g_async_queue_length (async_queue); + + PRINT_MSG (("sorted queue (for %d/%d times, size:%d)...", sorts, MAX_SORTS, len)); + } else { + can_quit = TRUE; + len = g_async_queue_length (async_queue); + DEBUG_MSG (("printing queue (size:%d)...", len)); + } + + for (i = 0, last_p = NULL; i < len; i++) { + p = g_async_queue_pop (async_queue); + DEBUG_MSG (("item %d ---> %d", i, GPOINTER_TO_INT (p))); + + if (last_p) { + g_assert (GPOINTER_TO_INT (last_p) <= GPOINTER_TO_INT (p)); + } + + last_p = p; + } + + if (can_quit && QUIT_WHEN_DONE) { + g_main_loop_quit (main_loop); + } + + return !can_quit; +} + +static void +enter_thread (gpointer data, gpointer user_data) +{ + gint len; + gint id; + gulong ms; + + id = GPOINTER_TO_INT (data); + + ms = g_random_int_range (MIN_TIME * 1000, MAX_TIME * 1000); + DEBUG_MSG (("entered thread with id:%d, adding to queue in:%ld ms", id, ms)); + + g_usleep (ms * 1000); + + if (SORT_QUEUE_ON_PUSH) { + g_async_queue_push_sorted (async_queue, GINT_TO_POINTER (id), sort_compare, NULL); + } else { + g_async_queue_push (async_queue, GINT_TO_POINTER (id)); + } + + len = g_async_queue_length (async_queue); + + DEBUG_MSG (("thread id:%d added to async queue (size:%d)", + id, len)); +} + +int +main (int argc, char *argv[]) +{ +#if defined(G_THREADS_ENABLED) && ! defined(G_THREADS_IMPL_NONE) + gint i; + gint max_threads = MAX_THREADS; + gint max_unused_threads = MAX_THREADS; + gint sort_multiplier = MAX_SORTS; + gint sort_interval; + gchar *msg; + + #ifdef __SYMBIAN32__ + g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); + g_set_print_handler(mrtPrintHandler); + #endif /*__SYMBIAN32__*/ + g_thread_init (NULL); + + PRINT_MSG (("creating async queue...")); + async_queue = g_async_queue_new (); + + g_return_val_if_fail (async_queue != NULL, EXIT_FAILURE); + + PRINT_MSG (("creating thread pool with max threads:%d, max unused threads:%d...", + max_threads, max_unused_threads)); + thread_pool = g_thread_pool_new (enter_thread, + async_queue, + max_threads, + FALSE, + NULL); + + g_return_val_if_fail (thread_pool != NULL, EXIT_FAILURE); + + g_thread_pool_set_max_unused_threads (max_unused_threads); + + PRINT_MSG (("creating threads...")); + for (i = 1; i <= max_threads; i++) { + GError *error = NULL; + + g_thread_pool_push (thread_pool, GINT_TO_POINTER (i), &error); + + g_assert_no_error (error); + } + + if (!SORT_QUEUE_AFTER) { + sort_multiplier = 1; + } + + sort_interval = ((MAX_TIME / sort_multiplier) + 2) * 1000; + g_timeout_add (sort_interval, sort_queue, GINT_TO_POINTER (sort_multiplier)); + + if (SORT_QUEUE_ON_PUSH) { + msg = "sorting when pushing into the queue, checking queue is sorted"; + } else { + msg = "sorting"; + } + + PRINT_MSG (("%s %d %s %d ms", + msg, + sort_multiplier, + sort_multiplier == 1 ? "time in" : "times, once every", + sort_interval)); + + DEBUG_MSG (("entering main event loop")); + + main_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (main_loop); + #endif + + #if __SYMBIAN32__ + testResultXml("asyncqueue-test"); + #endif /* EMULATOR */ + + return EXIT_SUCCESS; +}