/* John McCutchan 2005 */ #include "server_config.h" #include #include #include #include #include #include #include #include #include "gam_protocol.h" #include "gam_error.h" #include "gam_eq.h" // #define GAM_EQ_VERBOSE typedef struct { int reqno; int event; char *path; int len; } gam_eq_event_t; static gam_eq_event_t * gam_eq_event_new (int reqno, int event, const char *path, int len) { gam_eq_event_t *eq_event = NULL; eq_event = g_new0(gam_eq_event_t, 1); eq_event->reqno = reqno; eq_event->event = event; eq_event->path = g_strdup (path); eq_event->len = len; return eq_event; } static void gam_eq_event_free (gam_eq_event_t *event) { if (!event) return; g_free (event->path); g_free (event); } struct _gam_eq { GQueue *event_queue; }; gam_eq_t * gam_eq_new (void) { gam_eq_t *eq = NULL; eq = g_new0(struct _gam_eq, 1); eq->event_queue = g_queue_new (); return eq; } void gam_eq_free (gam_eq_t *eq) { if (!eq) return; while (!g_queue_is_empty (eq->event_queue)) { gam_eq_event_t *event = g_queue_pop_head (eq->event_queue); g_assert (event); gam_eq_event_free (event); } g_queue_free (eq->event_queue); g_free (eq); } void gam_eq_queue (gam_eq_t *eq, int reqno, int event, const char *path, int len) { gam_eq_event_t *eq_event; if (!eq) return; eq_event = g_queue_peek_tail (eq->event_queue); /* Check if the last event in the event queue is the same as the one we are attempting to queue * if it is, we can throw this new event away */ if (eq_event && eq_event->reqno == reqno && eq_event->len == len && eq_event->event == event && !strcmp(eq_event->path, path)) { #ifdef GAM_EQ_VERBOSE GAM_DEBUG(DEBUG_INFO, "gam_eq: Didn't queue duplicate event\n"); #endif return; } eq_event = gam_eq_event_new (reqno, event, path, len); g_queue_push_tail (eq->event_queue, eq_event); } guint gam_eq_size (gam_eq_t *eq) { if (!eq) return 0; return g_queue_get_length (eq->event_queue); } static void gam_eq_flush_callback (gam_eq_t *eq, gam_eq_event_t *event, GamConnDataPtr conn) { gam_send_event (conn, event->reqno, event->event, event->path, event->len); gam_eq_event_free (event); } gboolean gam_eq_flush (gam_eq_t *eq, GamConnDataPtr conn) { gboolean done_work = FALSE; if (!eq) return; #ifdef GAM_EQ_VERBOSE GAM_DEBUG(DEBUG_INFO, "gam_eq: Flushing event queue for %s\n", gam_connection_get_pidname (conn)); #endif while (!g_queue_is_empty (eq->event_queue)) { done_work = TRUE; gam_eq_event_t *event = g_queue_pop_head (eq->event_queue); g_assert (event); gam_eq_flush_callback (eq, event, conn); } return done_work; }