(root)/
glib-2.79.0/
glib/
tests/
asyncqueue.c
       1  /* Unit tests for GAsyncQueue
       2   * Copyright (C) 2011 Red Hat, Inc
       3   * Author: Matthias Clasen
       4   *
       5   * SPDX-License-Identifier: LicenseRef-old-glib-tests
       6   *
       7   * This work is provided "as is"; redistribution and modification
       8   * in whole or in part, in any medium, physical or electronic is
       9   * permitted without restriction.
      10   *
      11   * This work is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      14   *
      15   * In no event shall the authors or contributors be liable for any
      16   * direct, indirect, incidental, special, exemplary, or consequential
      17   * damages (including, but not limited to, procurement of substitute
      18   * goods or services; loss of use, data, or profits; or business
      19   * interruption) however caused and on any theory of liability, whether
      20   * in contract, strict liability, or tort (including negligence or
      21   * otherwise) arising in any way out of the use of this software, even
      22   * if advised of the possibility of such damage.
      23   */
      24  
      25  /* We are testing some deprecated APIs here */
      26  #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
      27  #define GLIB_DISABLE_DEPRECATION_WARNINGS
      28  #endif
      29  
      30  #include <glib.h>
      31  
      32  static gint
      33  compare_func (gconstpointer d1, gconstpointer d2, gpointer data)
      34  {
      35    gint i1, i2;
      36  
      37    i1 = GPOINTER_TO_INT (d1);
      38    i2 = GPOINTER_TO_INT (d2);
      39  
      40    return i1 - i2;
      41  }
      42  
      43  static
      44  void test_async_queue_sort (void)
      45  {
      46    GAsyncQueue *q;
      47  
      48    q = g_async_queue_new ();
      49  
      50    g_async_queue_push (q, GINT_TO_POINTER (10));
      51    g_async_queue_push (q, GINT_TO_POINTER (2));
      52    g_async_queue_push (q, GINT_TO_POINTER (7));
      53  
      54    g_async_queue_sort (q, compare_func, NULL);
      55  
      56    if (g_test_undefined ())
      57      {
      58        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      59                               "*assertion* failed*");
      60        g_async_queue_push_sorted (NULL, GINT_TO_POINTER (1),
      61                                   compare_func, NULL);
      62        g_test_assert_expected_messages ();
      63  
      64        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      65                               "*assertion* failed*");
      66        g_async_queue_push_sorted_unlocked (NULL, GINT_TO_POINTER (1),
      67                                            compare_func, NULL);
      68        g_test_assert_expected_messages ();
      69  
      70        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      71                               "*assertion* failed*");
      72        g_async_queue_sort (NULL, compare_func, NULL);
      73        g_test_assert_expected_messages ();
      74  
      75        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      76                               "*assertion* failed*");
      77        g_async_queue_sort (q, NULL, NULL);
      78        g_test_assert_expected_messages ();
      79  
      80        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      81                               "*assertion* failed*");
      82        g_async_queue_sort_unlocked (NULL, compare_func, NULL);
      83        g_test_assert_expected_messages ();
      84  
      85        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
      86                               "*assertion* failed*");
      87        g_async_queue_sort_unlocked (q, NULL, NULL);
      88        g_test_assert_expected_messages ();
      89      }
      90  
      91    g_async_queue_push_sorted (q, GINT_TO_POINTER (1), compare_func, NULL);
      92    g_async_queue_push_sorted (q, GINT_TO_POINTER (8), compare_func, NULL);
      93  
      94    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
      95    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
      96    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
      97    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 8);
      98    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
      99  
     100    g_assert_null (g_async_queue_try_pop (q));
     101  
     102    g_async_queue_unref (q);
     103  }
     104  
     105  static gint destroy_count;
     106  
     107  static void
     108  destroy_notify (gpointer item)
     109  {
     110    destroy_count++;
     111  }
     112  
     113  static void
     114  test_async_queue_destroy (void)
     115  {
     116    GAsyncQueue *q;
     117  
     118    destroy_count = 0;
     119  
     120    q = g_async_queue_new_full (destroy_notify);
     121  
     122    g_assert_cmpint (destroy_count, ==, 0);
     123  
     124    g_async_queue_push (q, GINT_TO_POINTER (1));
     125    g_async_queue_push (q, GINT_TO_POINTER (1));
     126    g_async_queue_push (q, GINT_TO_POINTER (1));
     127    g_async_queue_push (q, GINT_TO_POINTER (1));
     128  
     129    g_assert_cmpint (g_async_queue_length (q), ==, 4);
     130  
     131    g_async_queue_unref (q);
     132  
     133    g_assert_cmpint (destroy_count, ==, 4);
     134  }
     135  
     136  static GAsyncQueue *global_queue;
     137  
     138  static GThread *threads[10];
     139  static gint counts[10];
     140  static gint sums[10];
     141  static gint total;
     142  
     143  static gpointer
     144  thread_func (gpointer data)
     145  {
     146    gint pos = GPOINTER_TO_INT (data);
     147    gint value;
     148  
     149    while (1)
     150      {
     151        value = GPOINTER_TO_INT (g_async_queue_pop (global_queue));
     152  
     153        if (value == -1)
     154          break;
     155  
     156        counts[pos]++;
     157        sums[pos] += value;
     158  
     159        g_usleep (1000);
     160      }
     161  
     162    return NULL;
     163  }
     164  
     165  static void
     166  test_async_queue_threads (void)
     167  {
     168    gint i, j;
     169    gint s, c;
     170    gint value;
     171  
     172    global_queue = g_async_queue_new ();
     173  
     174    for (i = 0; i < 10; i++)
     175      threads[i] = g_thread_new ("test", thread_func, GINT_TO_POINTER (i));
     176  
     177    for (i = 0; i < 100; i++)
     178      {
     179        g_async_queue_lock (global_queue);
     180        for (j = 0; j < 10; j++)
     181          {
     182            value = g_random_int_range (1, 100);
     183            total += value;
     184            g_async_queue_push_unlocked (global_queue, GINT_TO_POINTER (value));
     185          }
     186        g_async_queue_unlock (global_queue);
     187  
     188        g_usleep (1000);
     189      }
     190  
     191    for (i = 0; i < 10; i++)
     192      g_async_queue_push (global_queue, GINT_TO_POINTER (-1));
     193  
     194    for (i = 0; i < 10; i++)
     195      g_thread_join (threads[i]);
     196  
     197    g_assert_cmpint (g_async_queue_length (global_queue), ==, 0);
     198  
     199    s = c = 0;
     200  
     201    for (i = 0; i < 10; i++)
     202      {
     203        g_assert_cmpint (sums[i], >, 0);
     204        g_assert_cmpint (counts[i], >, 0);
     205        s += sums[i];
     206        c += counts[i];
     207      }
     208  
     209    g_assert_cmpint (s, ==, total);
     210    g_assert_cmpint (c, ==, 1000);
     211  
     212    g_async_queue_unref (global_queue);
     213  }
     214  
     215  static void
     216  test_async_queue_timed (void)
     217  {
     218    GAsyncQueue *q;
     219    GTimeVal tv;
     220    gint64 start, end, diff;
     221    gpointer val;
     222  
     223    GDateTime *dt = g_date_time_new_now_utc ();
     224    int year = g_date_time_get_year (dt);
     225    g_date_time_unref (dt);
     226    if (year >= 2038)
     227      {
     228        g_test_skip ("Test relies on GTimeVal which is Y2038 unsafe and will cause a failure.");
     229        return;
     230      }
     231  
     232    g_get_current_time (&tv);
     233    if (g_test_undefined ())
     234      {
     235        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     236                               "*assertion* failed*");
     237        g_async_queue_timed_pop (NULL, &tv);
     238        g_test_assert_expected_messages ();
     239  
     240        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     241                               "*assertion* failed*");
     242        g_async_queue_timed_pop_unlocked (NULL, &tv);
     243        g_test_assert_expected_messages ();
     244      }
     245  
     246    q = g_async_queue_new ();
     247  
     248    start = g_get_monotonic_time ();
     249    g_assert_null (g_async_queue_timeout_pop (q, G_USEC_PER_SEC / 10));
     250  
     251    end = g_get_monotonic_time ();
     252    diff = end - start;
     253    g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
     254    /* diff should be only a little bit more than G_USEC_PER_SEC/10, but
     255     * we have to leave some wiggle room for heavily-loaded machines...
     256     */
     257    g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
     258  
     259    g_async_queue_push (q, GINT_TO_POINTER (10));
     260    val = g_async_queue_timed_pop (q, NULL);
     261    g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
     262    g_assert_null (g_async_queue_try_pop (q));
     263  
     264    start = end;
     265    g_get_current_time (&tv);
     266    g_time_val_add (&tv, G_USEC_PER_SEC / 10);
     267    g_assert_null (g_async_queue_timed_pop (q, &tv));
     268  
     269    end = g_get_monotonic_time ();
     270    diff = end - start;
     271    g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
     272    g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
     273  
     274    g_async_queue_push (q, GINT_TO_POINTER (10));
     275    val = g_async_queue_timed_pop_unlocked (q, NULL);
     276    g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
     277    g_assert_null (g_async_queue_try_pop (q));
     278  
     279    start = end;
     280    g_get_current_time (&tv);
     281    g_time_val_add (&tv, G_USEC_PER_SEC / 10);
     282    g_async_queue_lock (q);
     283    g_assert_null (g_async_queue_timed_pop_unlocked (q, &tv));
     284    g_async_queue_unlock (q);
     285  
     286    end = g_get_monotonic_time ();
     287    diff = end - start;
     288    g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
     289    g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
     290  
     291    g_async_queue_unref (q);
     292  }
     293  
     294  static void
     295  test_async_queue_remove (void)
     296  {
     297    GAsyncQueue *q;
     298  
     299    q = g_async_queue_new ();
     300  
     301    if (g_test_undefined ())
     302      {
     303        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     304                               "*assertion* failed*");
     305        g_async_queue_remove (NULL, GINT_TO_POINTER (1));
     306        g_test_assert_expected_messages ();
     307  
     308        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     309                               "*assertion* failed*");
     310        g_async_queue_remove (q, NULL);
     311        g_test_assert_expected_messages ();
     312  
     313        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     314                               "*assertion* failed*");
     315        g_async_queue_remove_unlocked (NULL, GINT_TO_POINTER (1));
     316        g_test_assert_expected_messages ();
     317  
     318        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     319                               "*assertion* failed*");
     320        g_async_queue_remove_unlocked (q, NULL);
     321        g_test_assert_expected_messages ();
     322      }
     323  
     324    g_async_queue_push (q, GINT_TO_POINTER (10));
     325    g_async_queue_push (q, GINT_TO_POINTER (2));
     326    g_async_queue_push (q, GINT_TO_POINTER (7));
     327    g_async_queue_push (q, GINT_TO_POINTER (1));
     328  
     329    g_async_queue_remove (q, GINT_TO_POINTER (7));
     330  
     331    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
     332    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
     333    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
     334  
     335    g_assert_null (g_async_queue_try_pop (q));
     336  
     337    g_async_queue_unref (q);
     338  }
     339  
     340  static void
     341  test_async_queue_push_front (void)
     342  {
     343    GAsyncQueue *q;
     344  
     345    q = g_async_queue_new ();
     346  
     347    if (g_test_undefined ())
     348      {
     349        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     350                               "*assertion* failed*");
     351        g_async_queue_push_front (NULL, GINT_TO_POINTER (1));
     352        g_test_assert_expected_messages ();
     353  
     354        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     355                               "*assertion* failed*");
     356        g_async_queue_push_front (q, NULL);
     357        g_test_assert_expected_messages ();
     358  
     359        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     360                               "*assertion* failed*");
     361        g_async_queue_push_front_unlocked (NULL, GINT_TO_POINTER (1));
     362        g_test_assert_expected_messages ();
     363  
     364        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     365                               "*assertion* failed*");
     366        g_async_queue_push_front_unlocked (q, NULL);
     367        g_test_assert_expected_messages ();
     368      }
     369  
     370    g_async_queue_push (q, GINT_TO_POINTER (10));
     371    g_async_queue_push (q, GINT_TO_POINTER (2));
     372    g_async_queue_push (q, GINT_TO_POINTER (7));
     373  
     374    g_async_queue_push_front (q, GINT_TO_POINTER (1));
     375  
     376    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
     377    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
     378    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
     379    g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
     380  
     381    g_assert_null (g_async_queue_try_pop (q));
     382  
     383    g_async_queue_unref (q);
     384  }
     385  
     386  static void
     387  test_basics (void)
     388  {
     389    GAsyncQueue *q;
     390    gpointer item;
     391  
     392    destroy_count = 0;
     393  
     394    if (g_test_undefined ())
     395      {
     396        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     397                               "*assertion* failed*");
     398        g_async_queue_length (NULL);
     399        g_test_assert_expected_messages ();
     400  
     401        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     402                               "*assertion* failed*");
     403        g_async_queue_length_unlocked (NULL);
     404        g_test_assert_expected_messages ();
     405  
     406        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     407                               "*assertion* failed*");
     408        g_async_queue_ref (NULL);
     409        g_test_assert_expected_messages ();
     410  
     411        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     412                               "*assertion* failed*");
     413        g_async_queue_ref_unlocked (NULL);
     414        g_test_assert_expected_messages ();
     415  
     416        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     417                               "*assertion* failed*");
     418        g_async_queue_unref (NULL);
     419        g_test_assert_expected_messages ();
     420  
     421        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     422                               "*assertion* failed*");
     423        g_async_queue_unref_and_unlock (NULL);
     424        g_test_assert_expected_messages ();
     425  
     426        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     427                               "*assertion* failed*");
     428        g_async_queue_lock (NULL);
     429        g_test_assert_expected_messages ();
     430  
     431        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     432                               "*assertion* failed*");
     433        g_async_queue_unlock (NULL);
     434        g_test_assert_expected_messages ();
     435  
     436        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     437                               "*assertion* failed*");
     438        g_async_queue_pop (NULL);
     439        g_test_assert_expected_messages ();
     440  
     441        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     442                               "*assertion* failed*");
     443        g_async_queue_pop_unlocked (NULL);
     444        g_test_assert_expected_messages ();
     445  
     446        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     447                               "*assertion* failed*");
     448        g_async_queue_try_pop (NULL);
     449        g_test_assert_expected_messages ();
     450  
     451        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     452                               "*assertion* failed*");
     453        g_async_queue_try_pop_unlocked (NULL);
     454        g_test_assert_expected_messages ();
     455  
     456        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     457                               "*assertion* failed*");
     458        g_async_queue_timeout_pop (NULL, 1);
     459        g_test_assert_expected_messages ();
     460  
     461        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     462                               "*assertion* failed*");
     463        g_async_queue_timeout_pop_unlocked (NULL, 1);
     464        g_test_assert_expected_messages ();
     465      }
     466  
     467    q = g_async_queue_new_full (destroy_notify);
     468  
     469    if (g_test_undefined ())
     470      {
     471        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     472                               "*assertion* failed*");
     473        g_async_queue_push (NULL, GINT_TO_POINTER (1));
     474        g_test_assert_expected_messages ();
     475  
     476        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     477                               "*assertion* failed*");
     478        g_async_queue_push (q, NULL);
     479        g_test_assert_expected_messages ();
     480  
     481        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     482                               "*assertion* failed*");
     483        g_async_queue_push_unlocked (NULL, GINT_TO_POINTER (1));
     484        g_test_assert_expected_messages ();
     485  
     486        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     487                               "*assertion* failed*");
     488        g_async_queue_push_unlocked (q, NULL);
     489        g_test_assert_expected_messages ();
     490      }
     491  
     492    g_async_queue_lock (q);
     493    g_async_queue_ref (q);
     494    g_async_queue_unlock (q);
     495    g_async_queue_lock (q);
     496    g_async_queue_ref_unlocked (q);
     497    g_async_queue_unref_and_unlock (q);
     498  
     499    item = g_async_queue_try_pop (q);
     500    g_assert_null (item);
     501  
     502    g_async_queue_lock (q);
     503    item = g_async_queue_try_pop_unlocked (q);
     504    g_async_queue_unlock (q);
     505    g_assert_null (item);
     506  
     507    g_async_queue_push (q, GINT_TO_POINTER (1));
     508    g_async_queue_push (q, GINT_TO_POINTER (2));
     509    g_async_queue_push (q, GINT_TO_POINTER (3));
     510    g_assert_cmpint (destroy_count, ==, 0);
     511  
     512    g_async_queue_unref (q);
     513    g_assert_cmpint (destroy_count, ==, 0);
     514  
     515    item = g_async_queue_pop (q);
     516    g_assert_cmpint (GPOINTER_TO_INT (item), ==, 1);
     517    g_assert_cmpint (destroy_count, ==, 0);
     518  
     519    g_async_queue_unref (q);
     520    g_assert_cmpint (destroy_count, ==, 2);
     521  }
     522  
     523  int
     524  main (int argc, char *argv[])
     525  {
     526    g_test_init (&argc, &argv, NULL);
     527  
     528    g_test_add_func ("/asyncqueue/basics", test_basics);
     529    g_test_add_func ("/asyncqueue/sort", test_async_queue_sort);
     530    g_test_add_func ("/asyncqueue/destroy", test_async_queue_destroy);
     531    g_test_add_func ("/asyncqueue/threads", test_async_queue_threads);
     532    g_test_add_func ("/asyncqueue/timed", test_async_queue_timed);
     533    g_test_add_func ("/asyncqueue/remove", test_async_queue_remove);
     534    g_test_add_func ("/asyncqueue/push_front", test_async_queue_push_front);
     535  
     536    return g_test_run ();
     537  }