The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
netgsource.c
Go to the documentation of this file.
1 
29 #include <projectcommon.h>
30 #include <memory.h>
31 #include <glib.h>
32 #include <frameset.h>
33 #include <netgsource.h>
34 
36 
44 
45 FSTATIC gboolean _netgsource_prepare(GSource* source, gint* timeout);
46 FSTATIC gboolean _netgsource_check(GSource* source);
47 FSTATIC gboolean _netgsource_dispatch(GSource* source, GSourceFunc callback, gpointer user_data);
48 FSTATIC void _netgsource_finalize(GSource* source);
50 FSTATIC void _netgsource_del_listener(gpointer);
53 
54 static GSourceFuncs _netgsource_gsourcefuncs = {
59  NULL,
60  NULL
61 };
62 FSTATIC void
64 {
65  Listener* lobj;
66  if (lptr) {
67  lobj = CASTTOCLASS(Listener, lptr);
68  UNREF(lobj);
69  }
70 }
71 
75  GDestroyNotify notify,
76  gint priority,
77  gboolean can_recurse,
79  GMainContext* context,
80  gsize objsize,
81  gpointer userdata
82  )
83 {
84  GSource* gsret;
85  NetGSource* ret;
86  GSourceFuncs* gsf;
87 
89  if (objsize < sizeof(NetGSource)) {
90  objsize = sizeof(NetGSource);
91  }
92  gsf = MALLOCBASECLASS(GSourceFuncs);
93  *gsf = _netgsource_gsourcefuncs;
94 
95  gsret = g_source_new(gsf, objsize);
96  if (gsret == NULL) {
97  FREECLASSOBJ(gsf);
98  g_return_val_if_reached(NULL);
99  }
100  proj_class_register_object(gsret, "GSource");
101  proj_class_register_subclassed(gsret, "NetGSource");
102  ret = CASTTOCLASS(NetGSource, gsret);
103 
104  ret->_gsfuncs = gsf;
105  ret->_userdata = userdata;
106  ret->_netio = iosrc;
107  iosrc->setblockio(iosrc, FALSE);
108  ret->_socket = iosrc->getfd(iosrc);
109  ret->_finalize = notify;
110  ret->_gfd.fd = ret->_socket;
111  ret->_gfd.events = G_IO_IN|G_IO_ERR|G_IO_HUP;
112  ret->_gfd.revents = 0;
116 
117  g_source_add_poll(gsret, &ret->_gfd);
118  g_source_set_priority(gsret, priority);
119  g_source_set_can_recurse(gsret, can_recurse);
120 
121  ret->_gsourceid = g_source_attach(gsret, context);
122 
123  if (ret->_gsourceid == 0) {
124  FREECLASSOBJ(gsf);
125  g_source_remove_poll(gsret, &ret->_gfd);
126  memset(ret, 0, sizeof(*ret));
127  g_source_unref(gsret);
128  gsret = NULL;
129  ret = NULL;
130  g_return_val_if_reached(NULL);
131  }
132  // REF(ret->_netio);
133  ret->_dispatchers = g_hash_table_new_full(NULL, NULL, NULL, _netgsource_del_listener);
134  return ret;
135 }
136 
139 FSTATIC gboolean
140 _netgsource_prepare(GSource* source,
141  gint* timeout)
142 {
143  (void)source; (void)timeout;
144  return _netgsource_check(source);
145 }
146 
150 FSTATIC gboolean
151 _netgsource_check(GSource* gself)
152 {
153  NetGSource* self = CASTTOCLASS(NetGSource, gself);
154  // revents: received events...
155  // @todo: probably should check for errors in revents
156  return ((0 != self->_gfd.revents) || self->_netio->input_queued(self->_netio));
157 }
163 FSTATIC gboolean
164 _netgsource_dispatch(GSource* gself,
165  GSourceFunc ignore_callback,
166  gpointer ignore_userdata)
167 {
168  NetGSource* self = CASTTOCLASS(NetGSource, gself);
169  GSList* gsl;
170  NetAddr* srcaddr;
171  (void)ignore_callback; (void)ignore_userdata;
172  if ((self->_gfd.revents & (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL|G_IO_PRI)) == 0) {
173  DEBUGMSG("%s.%d: Dispatched due to UNKNOWN REASON: 0x%04x"
174  , __FUNCTION__, __LINE__, self->_gfd.revents);
175  }
176  while(NULL != (gsl = self->_netio->recvframesets(self->_netio, &srcaddr))) {
177  for (; NULL != gsl; gsl = gsl->next) {
178  Listener* disp = NULL;
179  FrameSet* fs = CASTTOCLASS(FrameSet, gsl->data);
180  disp = g_hash_table_lookup(self->_dispatchers, GUINT_TO_POINTER((size_t)fs->fstype));
181  if (NULL == disp) {
182  disp = CASTTOCLASS(Listener, g_hash_table_lookup(self->_dispatchers, NULL));
183  }
184  if (NULL != disp) {
185  disp->got_frameset(disp, fs, srcaddr);
186  }else{
187  g_warning("No dispatcher for FrameSet type %d", fs->fstype);
188  }
189  }
190  UNREF(srcaddr);
191  }
192  return TRUE;
193 }
194 
196 FSTATIC void
197 _netgsource_finalize(GSource* gself)
198 {
199 #ifndef __FUNCTION__
200 # define __FUNCTION__ "_netgsource_finalize"
201 #endif
202  NetGSource* self = CASTTOCLASS(NetGSource, gself);
203  DEBUGMSG("%s(%p) FINALIZING!", __FUNCTION__, self);
204  if (self->_finalize) {
205  DEBUGMSG("%s: finalizing object at %p with %p", __FUNCTION__, self->_userdata
206  , self->_finalize);
207  self->_finalize(self->_userdata);
208  }else{
209  if (self->_userdata) {
212  FREECLASSOBJ(self->_userdata);
213  self->_userdata = NULL;
214  DEBUGMSG("%s: FREECLASSOBJ(%p)", __FUNCTION__, self->_userdata);
215  }
216  }
217  if (self->_gsfuncs) {
218  FREECLASSOBJ(self->_gsfuncs);
219  self->_gsfuncs = NULL;
220  }
221  // UNREF(self->_netio);
222  g_hash_table_unref(self->_dispatchers);
223  proj_class_dissociate(gself);// Avoid dangling reference in class system
224 }
226 FSTATIC void
228  const NetAddr* addr,
229  FrameSet* fs)
230 {
231  NetIO* nio = self->_netio;
232  nio->sendaframeset(nio, addr, fs);
233 }
235 FSTATIC void
237  const NetAddr* addr,
238  GSList* fslist)
239 {
240  NetIO* nio = self->_netio;
241  nio->sendframesets(nio, addr, fslist);
242 }
243 FSTATIC void
245  guint16 fstype,
246  Listener* disp)
247 {
248  if (disp) {
249  REF(disp);
250  }
251  g_hash_table_replace(self->_dispatchers, GUINT_TO_POINTER((size_t)fstype), disp);
252 }
FSTATIC gboolean _netgsource_prepare(GSource *source, gint *timeout)
GSource prepare routine for NetGSource - always returns TRUE Called before going into the select/poll...
Definition: netgsource.c:140
void setblockio(const NetIO *self, gboolean blocking)
<[in] Set blocking/non-blocking mode
FSTATIC gboolean _netgsource_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
GSource dispatch routine for NetGSource.
Definition: netgsource.c:164
GPollFD _gfd
Poll/select object for gmainloop.
Definition: netgsource.h:45
FSTATIC gboolean _netgsource_check(GSource *source)
GSource check routine for NetGSource.
Definition: netgsource.c:151
NetIO * _netio
netio this object is based on
Definition: netgsource.h:50
#define DEBUGMSG(...)
Definition: proj_classes.h:87
Implements minimal client-oriented Frame and Frameset capabilities.
#define MALLOCBASECLASS(Cclass)
Allocate memory for a C-class object of base class class G(not to be further subclassed) - and regist...
Definition: proj_classes.h:55
NetGSource * netgsource_new(NetIO *iosrc, GDestroyNotify notify, gint priority, gboolean can_recurse, GMainContext *context, gsize objsize, gpointer userdata)
Create a new (abstract) NetGSource object.
Definition: netgsource.c:74
void(* sendframesets)(NetGSource *, const NetAddr *, GSList *)
Send a frameset list.
Definition: netgsource.h:54
#define FSTATIC
Definition: projectcommon.h:31
tuple GSourceFunc
Definition: glib.py:68
#define FREECLASSOBJ(obj)
Free a C-class object.
Definition: proj_classes.h:76
guint16 fstype
Type of frameset.
Definition: frameset.h:51
#define BINDDEBUG(Cclass)
BINDDEBUG is for telling the class system where the debug variable for this class is - put it in the ...
Definition: proj_classes.h:82
gpointer _userdata
Saved user data.
Definition: netgsource.h:48
#define __FUNCTION__
void proj_class_register_object(gpointer object, const char *static_classname)
Log the creation of a new object, and its association with a given type.
Definition: proj_classes.c:100
gpointer proj_class_register_subclassed(gpointer object, const char *static_subclassname)
Log the creation of a subclassed object from a superclassed object.
Definition: proj_classes.c:192
void sendaframeset(NetIO *self, const NetAddr *dest, FrameSet *frameset)
< Send a FrameSet list to a NetIO class
#define REF(obj)
Definition: assimobj.h:39
gint getfd(const NetIO *self)
<[in] Return file/socket descriptor
Project common header file.
GSourceFuncs * _gsfuncs
pointers to GSource functions
Definition: netgsource.h:49
GHashTable * _dispatchers
Table of dispatch functions.
Definition: netgsource.h:51
FSTATIC void _netgsource_del_listener(gpointer)
Definition: netgsource.c:63
void(* addListener)(NetGSource *, guint16, Listener *)
Register a new listener.
Definition: netgsource.h:55
void proj_class_dissociate(gpointer object)
Dissociate an object from the C class system (typically coupled with freeing it). ...
Definition: proj_classes.c:228
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
gboolean(* got_frameset)(Listener *self, FrameSet *fs, NetAddr *na)
called when a FrameSet arrives
Definition: listener.h:45
gint _gsourceid
Source ID from g_source_attach()
Definition: netgsource.h:47
void(* sendaframeset)(NetGSource *, const NetAddr *, FrameSet *)
Send a single frameset.
Definition: netgsource.h:53
FSTATIC void _netgsource_finalize(GSource *source)
Finalize (free) the NetGSource object.
Definition: netgsource.c:197
FrameSet class - used for collecting Frames when not on the wire, and for marshalling/demarshalling t...
Definition: frameset.h:45
FSTATIC void _netgsource_addListener(NetGSource *, guint16, Listener *)
Definition: netgsource.c:244
GDestroyNotify _finalize
Function to call when we're destroyed.
Definition: netgsource.h:52
Implements NetIO GSource object.
#define DEBUGDECLARATIONS
Definition: proj_classes.h:79
FSTATIC void _netgsource_sendaframeset(NetGSource *, const NetAddr *, FrameSet *)
Send a single frameset to the given address.
Definition: netgsource.c:227
FSTATIC void _netgsource_sendframesets(NetGSource *, const NetAddr *, GSList *)
Send a (GSList) list of FrameSets to the given address.
Definition: netgsource.c:236
#define CASTTOCLASS(Cclass, obj)
Safely cast 'obj' to C-class 'class' - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
This is a basic NetIO class abstract class for doing network I/O.
Definition: netio.h:58
The NetGSource class objects integrate NetIO class objects into the g_main_loop paradigm.
Definition: netgsource.h:43
This is the Listener class. object - which generically listens for packets.
Definition: listener.h:41
int _socket
Underlying socket descriptor.
Definition: netgsource.h:46
void sendframesets(NetIO *self, const NetAddr *dest, GSList *framesets)
< Send a FrameSet list to a NetIO class
struct _NetGSource NetGSource
Definition: netgsource.h:34