aboutsummaryrefslogtreecommitdiff
path: root/src/lib/common/gnunet_dbus_lib_signal.c
blob: 05972003aa787bce8e8bc03ec9e6df36b4983726 (plain) (blame)
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "config.h"

#include <gnunet/platform.h>
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_container_lib.h>

#include "gnunet_dbus_lib.h"

#define LOG(kind, ...) GNUNET_log_from (kind, "dbus-signal", __VA_ARGS__)

struct GNUNET_DBUS_Signal
{
  struct GNUNET_DBUS_ArgIterator *args_front;
  struct GNUNET_DBUS_ArgIterator *args_back;

  struct GNUNET_DBUS_Interface *owner;

  char *name;

  unsigned ref_count;
};

struct GNUNET_DBUS_Signal *
GNUNET_DBUS_signal_create (
  const char *name)
{
  struct GNUNET_DBUS_Signal *ret = GNUNET_new (struct GNUNET_DBUS_Signal);
  ret->args_front = NULL;
  ret->args_back  = NULL;
  ret->owner = NULL;
  ret->name = strdup (name);
  ret->ref_count = 1;

  return ret;
}

void
GNUNET_DBUS_signal_ref (
    struct GNUNET_DBUS_Signal *signal)
{
  signal->ref_count++;
}

void
GNUNET_DBUS_signal_unref (
    struct GNUNET_DBUS_Signal *signal)
{
  if (signal->ref_count == 0)
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference signal with ref count 0.\n");
    GNUNET_abort_ ();
  }
  if (0 == --(signal->ref_count))
  {
    struct GNUNET_DBUS_ArgIterator *arg_it = signal->args_front;
    while (arg_it)
    {
      struct GNUNET_DBUS_ArgIterator *next = arg_it->next;
      GNUNET_DBUS_arg_unref (arg_it->arg);
      GNUNET_free (arg_it);
      arg_it = next;
    }

    GNUNET_free (signal->name);
    GNUNET_free (signal);
  }
};

void
GNUNET_DBUS_signal_add_arg (
    struct GNUNET_DBUS_Signal *signal,
    const char *name,
    const char *signature)
{
  struct GNUNET_DBUS_Arg *arg = GNUNET_DBUS_arg_create (name, signature);
  struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_new (struct GNUNET_DBUS_ArgIterator);
  arg_it->arg = arg;
  GNUNET_CONTAINER_DLL_insert_tail (signal->args_front,
                                    signal->args_back,
                                    arg_it);
};

const char *
GNUNET_DBUS_signal_get_name (
    const struct GNUNET_DBUS_Signal *signal)
{
  return signal->name;
}

const struct GNUNET_DBUS_ArgIterator *
GNUNET_DBUS_signal_iterate_args (
    const struct GNUNET_DBUS_Signal *signal)
{
  return signal->args_front;
}

DBusMessage *
GNUNET_DBUS_signal_spawn (
    const struct GNUNET_DBUS_Signal *signal,
    const struct GNUNET_DBUS_ObjectPath *path,
    const struct GNUNET_DBUS_Interface *interface,
    bool pretty)
{
  char *path_str = GNUNET_DBUS_object_path_to_string (path);
  DBusMessage *ret = dbus_message_new_signal (
      path_str,
      GNUNET_DBUS_interface_get_name (interface),
      signal->name);
  GNUNET_free (path_str);
  GNUNET_DBUS_message_set_pretty (ret, pretty);
  return ret;
};

DBusMessage *
GNUNET_DBUS_signal_spawn_unicast (
    const struct GNUNET_DBUS_Signal *signal,
    const struct GNUNET_DBUS_ObjectPath *path,
    const struct GNUNET_DBUS_Interface *interface,
    const struct GNUNET_DBUS_Client *client,
    bool pretty)
{
  DBusMessage *ret = GNUNET_DBUS_signal_spawn (signal, path, interface, pretty);
  dbus_message_set_destination (ret, GNUNET_DBUS_client_get_unique_name (client));
  return ret;
}