summaryrefslogtreecommitdiff
path: root/tests/dconf-mock-shm.c
blob: 3e9c38dbc409098dae319904d696703f7b4c26bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "../shm/dconf-shm.h"

#include "dconf-mock.h"

typedef struct
{
  guint8 flagged;
  gint   ref_count;
} DConfMockShm;

static GHashTable *dconf_mock_shm_table;
static GMutex      dconf_mock_shm_lock;

static void
dconf_mock_shm_unref (gpointer data)
{
  DConfMockShm *shm = data;

  if (g_atomic_int_dec_and_test (&shm->ref_count))
    g_slice_free (DConfMockShm, shm);
}

static DConfMockShm *
dconf_mock_shm_ref (DConfMockShm *shm)
{
  g_atomic_int_inc (&shm->ref_count);

  return shm;
}

guint8 *
dconf_shm_open (const gchar *name)
{
  DConfMockShm *shm;

  g_mutex_lock (&dconf_mock_shm_lock);

  if G_UNLIKELY (dconf_mock_shm_table == NULL)
    dconf_mock_shm_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, dconf_mock_shm_unref);

  shm = g_hash_table_lookup (dconf_mock_shm_table, name);
  if (shm == NULL)
    {
      shm = g_slice_new0 (DConfMockShm);
      g_hash_table_insert (dconf_mock_shm_table, g_strdup (name), dconf_mock_shm_ref (shm));
    }

  /* before unlocking... */
  dconf_mock_shm_ref (shm);

  g_mutex_unlock (&dconf_mock_shm_lock);

  return &shm->flagged;
}

void
dconf_shm_close (guint8 *shm)
{
  if (shm)
    dconf_mock_shm_unref (shm);
}

void
dconf_mock_shm_reset (void)
{
  g_mutex_lock (&dconf_mock_shm_lock);
  if (dconf_mock_shm_table != NULL)
    {
      GHashTableIter iter;
      gpointer value;

      g_hash_table_iter_init (&iter, dconf_mock_shm_table);
      while (g_hash_table_iter_next (&iter, NULL, &value))
        {
          DConfMockShm *shm = value;

          g_assert_cmpint (shm->ref_count, ==, 1);
          g_hash_table_iter_remove (&iter);
        }
    }
  g_mutex_unlock (&dconf_mock_shm_lock);
}