The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hbsender.c
Go to the documentation of this file.
1 
23 #include <memory.h>
24 #include <glib.h>
25 #include <frameset.h>
26 #include <frame.h>
27 #include <hbsender.h>
30 FSTATIC void _hbsender_notify_function(gpointer data);
32 FSTATIC void _hbsender_ref(HbSender * self);
33 FSTATIC void _hbsender_unref(HbSender * self);
37 FSTATIC gboolean _hbsender_gsourcefunc(gpointer);
38 
40 
45 
46 static GSList* _hb_senders = NULL;
47 static gint _hb_sender_count = 0;
48 
49 #define ONESEC 1000000
50 
52 FSTATIC void
54 {
55  _hb_senders = g_slist_prepend(_hb_senders, self);
56  _hb_sender_count += 1;
57 }
58 
60 FSTATIC void
62 {
63  if (g_slist_find(_hb_senders, self) != NULL) {
64  _hb_senders = g_slist_remove(_hb_senders, self);
65  _hb_sender_count -= 1;
66  return;
67  }
68  g_warn_if_reached();
69 }
70 
72 FSTATIC gboolean
73 _hbsender_gsourcefunc(gpointer gself)
74 {
75  HbSender* self = CASTTOCLASS(HbSender, gself);
77  return TRUE;
78 }
79 
80 
82 FSTATIC void
84 {
85  self->_refcount += 1;
86 }
87 
89 FSTATIC void
91 {
92  g_return_if_fail(self->_refcount > 0);
93  self->_refcount -= 1;
94  if (self->_refcount == 0) {
95  _hbsender_dellist(self);
96  self->_finalize(self);
97  self = NULL;
98  }
99 }
100 // Callback function from the GSource world - notifying us when we're getting shut down from their end
101 FSTATIC void
103 {
104  HbSender* self = CASTTOCLASS(HbSender, data);
105  self->timeout_source = 0;
106 }
107 
109 FSTATIC void
111 {
112  if (self->_sendaddr) {
113  UNREF(self->_sendaddr);
114  }
115  if (self->timeout_source != 0) {
116  g_source_remove(self->timeout_source);
117  }
118  memset(self, 0x00, sizeof(*self));
119  FREECLASSOBJ(self);
120 }
121 
122 
125 HbSender*
127  NetGSource* outmethod,
128  guint interval,
129  gsize objsize)
130 {
131  HbSender * newsender;
133  if (objsize < sizeof(HbSender)) {
134  objsize = sizeof(HbSender);
135  }
136  newsender = MALLOCCLASS(HbSender, objsize);
137  if (newsender != NULL) {
138  newsender->_sendaddr = sendaddr;
139  REF(sendaddr);
140  newsender->_refcount = 1;
141  newsender->ref = _hbsender_ref;
142  newsender->_outmethod = outmethod;
143  newsender->unref = _hbsender_unref;
144  newsender->_finalize = _hbsender_finalize;
145  newsender->_expected_interval = interval;
146  if (interval < 500000) {
147  interval = 1000000;
148  }
149  newsender->timeout_source = g_timeout_add_seconds_full
150  (G_PRIORITY_HIGH, (interval/1000000), _hbsender_gsourcefunc
151  , newsender, _hbsender_notify_function);
152  DEBUGMSG3("Sender %p timeout source is: %d, interval is %d", newsender
153  , newsender->timeout_source, interval);
154  _hbsender_addlist(newsender);
155  // Avoid Martian packets - don't send the first one right away...
156  // _hbsender_sendheartbeat(newsender);
157  }
158  return newsender;
159 }
160 
161 
163 void
165 {
166  GSList* obj;
167  for (obj = _hb_senders; obj != NULL; obj=obj->next) {
168  HbSender* sender = CASTTOCLASS(HbSender, obj->data);
169  if (sendaddr->equal(sendaddr, sender->_sendaddr)) {
170  sender->unref(sender);
171  return;
172  }
173  }
174 }
175 FSTATIC void
177 {
179  //g_debug("Sending a heartbeat...");
180  self->_outmethod->sendaframeset(self->_outmethod, self->_sendaddr, heartbeat);
181  UNREF(heartbeat);
182 }
183 void
185 {
186  while (_hb_senders) {
187  HbSender* sender = CASTTOCLASS(HbSender, _hb_senders->data);
188  sender->unref(sender);
189  }
190 }