Merge branch 'gbytes-compare-docs' into 'master'
[glib.git] / gio / inotify / inotify-missing.c
blobb71b2d339a07788c1ad1c2e93ee9595e4faa734c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */
3 /* inotify-missing.c - GVFS Monitor based on inotify.
5 Copyright (C) 2005 John McCutchan
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.1 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 Public License
18 along with this library; if not, see <http://www.gnu.org/licenses/>.
20 Authors:
21 John McCutchan <john@johnmccutchan.com>
24 #include "config.h"
25 #include <glib.h>
26 #include "inotify-missing.h"
27 #include "inotify-path.h"
28 #include "glib-private.h"
30 #define SCAN_MISSING_TIME 4 /* 1/4 Hz */
32 static gboolean im_debug_enabled = FALSE;
33 #define IM_W if (im_debug_enabled) g_warning
35 /* We put inotify_sub's that are missing on this list */
36 static GList *missing_sub_list = NULL;
37 static gboolean im_scan_missing (gpointer user_data);
38 static gboolean scan_missing_running = FALSE;
39 static void (*missing_cb)(inotify_sub *sub) = NULL;
41 G_LOCK_EXTERN (inotify_lock);
43 /* inotify_lock must be held before calling */
44 void
45 _im_startup (void (*callback)(inotify_sub *sub))
47 static gboolean initialized = FALSE;
49 if (!initialized)
51 missing_cb = callback;
52 initialized = TRUE;
56 /* inotify_lock must be held before calling */
57 void
58 _im_add (inotify_sub *sub)
60 if (g_list_find (missing_sub_list, sub))
62 IM_W ("asked to add %s to missing list but it's already on the list!\n", sub->dirname);
63 return;
66 IM_W ("adding %s to missing list\n", sub->dirname);
67 missing_sub_list = g_list_prepend (missing_sub_list, sub);
69 /* If the timeout is turned off, we turn it back on */
70 if (!scan_missing_running)
72 GSource *source;
74 scan_missing_running = TRUE;
75 source = g_timeout_source_new_seconds (SCAN_MISSING_TIME);
76 g_source_set_callback (source, im_scan_missing, NULL, NULL);
77 g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
78 g_source_unref (source);
82 /* inotify_lock must be held before calling */
83 void
84 _im_rm (inotify_sub *sub)
86 GList *link;
88 link = g_list_find (missing_sub_list, sub);
90 if (!link)
92 IM_W ("asked to remove %s from missing list but it isn't on the list!\n", sub->dirname);
93 return;
96 IM_W ("removing %s from missing list\n", sub->dirname);
98 missing_sub_list = g_list_remove_link (missing_sub_list, link);
99 g_list_free_1 (link);
102 /* Scans the list of missing subscriptions checking if they
103 * are available yet.
105 static gboolean
106 im_scan_missing (gpointer user_data)
108 GList *nolonger_missing = NULL;
109 GList *l;
111 G_LOCK (inotify_lock);
113 IM_W ("scanning missing list with %d items\n", g_list_length (missing_sub_list));
114 for (l = missing_sub_list; l; l = l->next)
116 inotify_sub *sub = l->data;
117 gboolean not_m = FALSE;
119 IM_W ("checking %p\n", sub);
120 g_assert (sub);
121 g_assert (sub->dirname);
122 not_m = _ip_start_watching (sub);
124 if (not_m)
126 missing_cb (sub);
127 IM_W ("removed %s from missing list\n", sub->dirname);
128 /* We have to build a list of list nodes to remove from the
129 * missing_sub_list. We do the removal outside of this loop.
131 nolonger_missing = g_list_prepend (nolonger_missing, l);
135 for (l = nolonger_missing; l ; l = l->next)
137 GList *llink = l->data;
138 missing_sub_list = g_list_remove_link (missing_sub_list, llink);
139 g_list_free_1 (llink);
142 g_list_free (nolonger_missing);
144 /* If the missing list is now empty, we disable the timeout */
145 if (missing_sub_list == NULL)
147 scan_missing_running = FALSE;
148 G_UNLOCK (inotify_lock);
149 return FALSE;
151 else
153 G_UNLOCK (inotify_lock);
154 return TRUE;