static void node_emit_events(node_t *f, const node_event_t *ne) { gsize num = sizeof(concern_events)/sizeof(int); gint i; int translated_e; node_t *p; if (node_timeval_lt(&f->atv, &ne->ctv)) { int event = ne->e; /* Emit DELETED on the pair_data */ if (ne->pair_data) { node_t *from = ne->pair_data; node_emit_one_event(from, from->dir_subs, NULL, node_event_translate(FILE_DELETE, FALSE)); node_emit_one_event(from, from->subs, NULL, node_event_translate(FILE_DELETE, FALSE)); } for (i = 0; i < num; i++) { if (event & concern_events[i]) { translated_e = node_event_translate(concern_events[i], FALSE); /* Neither GIO or gamin cares about modified events on a * directory. */ #ifdef GIO_COMPILATION if ((concern_events[i] & FILE_MODIFIED) == 0) { node_emit_one_event(f, f->dir_subs, NULL, translated_e); } #else /* Gamin doesn't care about attrib changed events on a directory * either. */ if ((concern_events[i] & (FILE_MODIFIED | FILE_ATTRIB)) == 0) { node_emit_one_event(f, f->dir_subs, NULL, translated_e); } #endif node_emit_one_event(f, f->subs, NULL, translated_e); } event &= ~concern_events[i]; } } p = NODE_PARENT(f); if (p != NULL && node_timeval_lt(&p->atv, &ne->ctv)) { int event = ne->e; for (i = 0; i < num; i++) { if (event & concern_events[i]) { translated_e = node_event_translate(concern_events[i], ne->pair_data != NULL); node_emit_one_event(f, p->dir_subs, ne->pair_data, translated_e); node_emit_one_event(f, p->subs, ne->pair_data, translated_e); } event &= ~concern_events[i]; } } }
static gboolean port_events_process_cb(gpointer user_data) { node_event_t *ev; G_LOCK (fen_lock); /* Processing g_eventq */ while ((ev = (node_event_t*)g_queue_pop_head (g_eventq)) != NULL) { /* FK_W ("[%s] 0x%p %s\n", __func__, ev, _event_string (ev->e)); */ { gchar *log = _event_strings(ev->e); FK_W ("%s %s %s\n", __func__, NODE_NAME(ev->user_data), log); g_free(log); } #ifdef GIO_COMPILATION /* Use the parent node as a hash, because only the dir_subs in the * parent node should receive MOVE event. */ if (NODE_PARENT(ev->user_data)) { if (ev->e == FILE_RENAME_TO) { g_hash_table_insert(renamed_hash, NODE_PARENT(ev->user_data), ev); g_time_val_add(&ev->rename_tv, RENAME_EVENTS_INTERVAL); continue; } if (ev->e == FILE_RENAME_FROM) { node_event_t *pair_ev; pair_ev = g_hash_table_lookup(renamed_hash, NODE_PARENT(ev->user_data)); if (pair_ev && node_timeval_lt(&ev->ctv, &pair_ev->rename_tv)) { g_hash_table_remove(renamed_hash, NODE_PARENT(ev->user_data)); pair_ev->pair_data = ev->user_data; /* Free ev, exchange pair_ev and ev. */ node_event_delete(ev); ev = pair_ev; } } } #endif #if 0 node_add_event(ev->user_data, ev); #else user_process_events_cb(ev->user_data, ev); #endif } /* Processing the events in renamed_hash. TODO we should delay it and wait * for more possible pair. */ g_hash_table_foreach_remove(renamed_hash, process_renamed_hash_cb, NULL); G_UNLOCK (fen_lock); process_port_event_id = 0; return FALSE; }