1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:set expandtab ts=4 shiftwidth=4: */
4 * Copyright (c) 2008, 2010 Oracle and/or its affiliates, Inc. All rights
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307, USA.
22 * Authors: Lin Ma <lin.ma@sun.com>
27 #include "fen-helper.h"
28 #include "fen-kernel.h"
29 #ifdef GIO_COMPILATION
30 #include <gio/gfilemonitor.h>
32 #include "gam_event.h"
33 #include "gam_server.h"
34 #include "gam_protocol.h"
37 #ifdef GIO_COMPILATION
38 #define FH_W if (FALSE) g_debug
40 #include "gam_error.h"
41 #define FH_W(...) GAM_DEBUG(DEBUG_INFO, __VA_ARGS__)
44 G_LOCK_EXTERN (fen_lock);
48 scan_children_init(node_t *f, gpointer sub)
53 FH_W ("%s %s [0x%p]\n", __func__, NODE_NAME(f), f);
55 #ifdef GIO_COMPILATION
57 event = G_FILE_MONITOR_EVENT_CREATED;
60 event = GAMIN_EVENT_EXISTS;
63 if (!NODE_HAS_FLAG(f, NODE_FLAG_SNAPSHOT_UPDATED)) {
64 /* TODO snapshot should also compare to the sub created timestamp. */
65 /* GIO initially doesn't emit created/existed events. */
66 node_create_children_snapshot(f, event, emit);
71 g_hash_table_iter_init (&iter, f->children);
72 while (g_hash_table_iter_next (&iter, NULL, &value)) {
73 node_t *child = (node_t *)value;
75 #ifdef GIO_COMPILATION
76 /* GIO initially doesn't emit created/existed events. */
77 /* g_file_monitor_emit_event(G_FILE_MONITOR(sub), child->gfile, NULL, event); */
79 gam_server_emit_one_event(NODE_NAME(child), gam_subscription_is_dir(sub), event, sub, 1);
88 * Won't hold a ref, we have a timout callback to clean unused node_t.
89 * If there is no value for a key, add it and return it; else return the old
93 fen_add (const gchar *filename, gpointer sub, gboolean is_mondir)
101 f = node_find(NULL, filename, TRUE);
102 FH_W ("%s 0x%p sub[0x%p] %s\n", __func__, f, sub, filename);
105 /* Update timestamp, the events in global queue will compare itself to this
106 * timestamp to decide if be emitted. TODO, timestamp should be per sub.
108 if (!NODE_IS_ACTIVE(f)) {
109 g_get_current_time(&f->atv);
113 f->dir_subs = g_list_prepend(f->dir_subs, sub);
115 f->subs = g_list_prepend(f->subs, sub);
118 if (NODE_HAS_STATE(f, NODE_STATE_ASSOCIATED) ||
119 (node_lstat(f) == 0 && port_add(f) == 0)) {
120 #ifndef GIO_COMPILATION
121 gam_server_emit_one_event (NODE_NAME(f),
122 gam_subscription_is_dir (sub), GAMIN_EVENT_EXISTS, sub, 1);
125 scan_children_init (f, sub);
128 #ifndef GIO_COMPILATION
129 gam_server_emit_one_event (NODE_NAME(f),
130 gam_subscription_is_dir (sub), GAMIN_EVENT_DELETED, sub, 1);
132 node_adjust_deleted (f);
134 #ifndef GIO_COMPILATION
135 gam_server_emit_one_event (NODE_NAME(f),
136 gam_subscription_is_dir (sub), GAMIN_EVENT_ENDEXISTS, sub, 1);
142 fen_remove (const gchar *filename, gpointer sub, gboolean is_mondir)
150 f = node_find(NULL, filename, FALSE);
151 FH_W ("%s 0x%p sub[0x%p] %s\n", __func__, f, sub, filename);
155 f->dir_subs = g_list_remove(f->dir_subs, sub);
157 f->subs = g_list_remove(f->subs, sub);
160 if (!NODE_IS_ACTIVE(f)) {
170 * FEN subsystem initializing.
175 static gboolean initialized = FALSE;
176 static gboolean result = FALSE;
184 result = node_class_init();