/** * fen_add * * Won't hold a ref, we have a timout callback to clean unused node_t. * If there is no value for a key, add it and return it; else return the old * one. */ void fen_add (const gchar *filename, gpointer sub, gboolean is_mondir) { node_t* f; g_assert (filename); g_assert (sub); G_LOCK (fen_lock); f = node_find(NULL, filename, TRUE); FH_W ("%s 0x%p sub[0x%p] %s\n", __func__, f, sub, filename); g_assert (f); /* Update timestamp, the events in global queue will compare itself to this * timestamp to decide if be emitted. TODO, timestamp should be per sub. */ if (!NODE_IS_ACTIVE(f)) { g_get_current_time(&f->atv); } if (is_mondir) { f->dir_subs = g_list_prepend(f->dir_subs, sub); } else { f->subs = g_list_prepend(f->subs, sub); } if (NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED) || (node_lstat(f) == 0 && port_add(f) == 0)) { #ifndef GIO_COMPILATION gam_server_emit_one_event (NODE_NAME(f), gam_subscription_is_dir (sub), GAMIN_EVENT_EXISTS, sub, 1); #endif if (is_mondir) { scan_children_init (f, sub); } } else { #ifndef GIO_COMPILATION gam_server_emit_one_event (NODE_NAME(f), gam_subscription_is_dir (sub), GAMIN_EVENT_DELETED, sub, 1); #endif node_adjust_deleted (f); } #ifndef GIO_COMPILATION gam_server_emit_one_event (NODE_NAME(f), gam_subscription_is_dir (sub), GAMIN_EVENT_ENDEXISTS, sub, 1); #endif G_UNLOCK (fen_lock); }
/* * node_add_event: * */ static void node_add_event (node_t *f, node_event_t *ev) { FN_W ("%s %d\n", __func__, ev->e); /* Clean the events flag early, because all received events need be * processed in this function. */ NODE_CLE_STATE(f, NODE_STATE_HAS_EVENTS); /* * Node the node has been created, so we can delete create event in * optimizing. To reduce the statings, we add it to Port on discoving * it then emit CREATED event. So we don't need to do anything here. */ if (NODE_NEED_MONITOR(f)) { if (HAS_NO_EXCEPTION_EVENTS(ev->e)) { if (NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED) || port_add(f) == 0) { if ((ev->e & FILE_MODIFIED) && NODE_HAS_FLAG(f, NODE_FLAG_DIR)) { if (f->dir_subs) { node_create_children_snapshot(f, FN_EVENT_CREATED, TRUE); } else { g_hash_table_foreach(f->children, foreach_known_children_scan, NULL); } } } else { /* Emit delete event */ ev->e |= FILE_DELETE; node_adjust_deleted(f); } } else { node_adjust_deleted(f); } /* Send events to clients. */ node_emit_events (f, ev); } else { /* Send events to clients. */ node_emit_events (f, ev); node_try_delete(f); } if (ev->pair_data) { node_t *from = ev->pair_data; g_assert(ev->e == FILE_RENAME_TO); if (NODE_NEED_MONITOR(from)) { /* Clean the events flag, since it may block free this node. */ NODE_CLE_STATE(from, NODE_STATE_HAS_EVENTS); node_adjust_deleted(from); } else { node_try_delete(from); } } node_event_delete (ev); }