1 /* Virtual File System garbage collection code
2 Copyright (C) 1995-2003 The Free Software Foundation
4 Written by: 1995 Miguel de Icaza
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License
11 as published by the Free Software Foundation; either version 2 of
12 the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 #include <stdlib.h> /* For atol() */
30 #include <sys/types.h>
32 #include <ctype.h> /* is_digit() */
39 #include "../src/panel.h" /* get_current_panel() */
40 #include "../src/layout.h" /* get_current_type() */
43 int vfs_timeout
= 60; /* VFS timeout in seconds */
45 static struct vfs_stamping
*stamps
;
49 vfs_addstamp (struct vfs_class
*v
, vfsid id
)
51 if (!(v
->flags
& VFSF_LOCAL
) && id
!= NULL
) {
52 struct vfs_stamping
*stamp
;
53 struct vfs_stamping
*last_stamp
= NULL
;
55 for (stamp
= stamps
; stamp
!= NULL
; stamp
= stamp
->next
) {
56 if (stamp
->v
== v
&& stamp
->id
== id
) {
57 gettimeofday (&(stamp
->time
), NULL
);
62 stamp
= g_new (struct vfs_stamping
, 1);
66 gettimeofday (&(stamp
->time
), NULL
);
71 last_stamp
->next
= stamp
;
73 /* Add first element */
81 vfs_stamp (struct vfs_class
*v
, vfsid id
)
83 struct vfs_stamping
*stamp
;
85 for (stamp
= stamps
; stamp
!= NULL
; stamp
= stamp
->next
)
86 if (stamp
->v
== v
&& stamp
->id
== id
) {
87 gettimeofday (&(stamp
->time
), NULL
);
94 vfs_rmstamp (struct vfs_class
*v
, vfsid id
)
96 struct vfs_stamping
*stamp
, *st1
;
98 for (stamp
= stamps
, st1
= NULL
; stamp
!= NULL
;
99 st1
= stamp
, stamp
= stamp
->next
)
100 if (stamp
->v
== v
&& stamp
->id
== id
) {
102 stamps
= stamp
->next
;
104 st1
->next
= stamp
->next
;
113 /* Find VFS id for given directory name */
115 vfs_getid (struct vfs_class
*vclass
, const char *dir
)
120 /* append slash if needed */
121 dir1
= concat_dir_and_file (dir
, "");
123 id
= (*vclass
->getid
) (vclass
, dir1
);
131 vfs_stamp_path (char *path
)
133 struct vfs_class
*vfs
;
136 vfs
= vfs_get_class (path
);
137 id
= vfs_getid (vfs
, path
);
138 vfs_addstamp (vfs
, id
);
143 * Create a new timestamp item by VFS class and VFS id.
146 vfs_stamp_create (struct vfs_class
*oldvfs
, vfsid oldvfsid
)
148 struct vfs_class
*nvfs
, *n2vfs
, *n3vfs
;
149 vfsid nvfsid
, n2vfsid
, n3vfsid
;
151 /* There are three directories we have to take care of: current_dir,
152 current_panel->cwd and other_panel->cwd. Athough most of the time either
153 current_dir and current_panel->cwd or current_dir and other_panel->cwd are the
154 same, it's possible that all three are different -- Norbert */
159 nvfs
= vfs_get_class (vfs_get_current_dir ());
160 nvfsid
= vfs_getid (nvfs
, vfs_get_current_dir ());
161 vfs_rmstamp (nvfs
, nvfsid
);
163 if ((nvfs
== oldvfs
&& nvfsid
== oldvfsid
) || oldvfsid
== NULL
) {
167 if (get_current_type () == view_listing
) {
168 n2vfs
= vfs_get_class (current_panel
->cwd
);
169 n2vfsid
= vfs_getid (n2vfs
, current_panel
->cwd
);
170 if (n2vfs
== oldvfs
&& n2vfsid
== oldvfsid
)
177 if (get_other_type () == view_listing
) {
178 n3vfs
= vfs_get_class (other_panel
->cwd
);
179 n3vfsid
= vfs_getid (n3vfs
, other_panel
->cwd
);
180 if (n3vfs
== oldvfs
&& n3vfsid
== oldvfsid
)
187 if (!oldvfs
->nothingisopen
|| !(*oldvfs
->nothingisopen
) (oldvfsid
))
190 vfs_addstamp (oldvfs
, oldvfsid
);
195 vfs_add_current_stamps (void)
197 vfs_stamp_path (vfs_get_current_dir ());
200 if (get_current_type () == view_listing
)
201 vfs_stamp_path (current_panel
->cwd
);
205 if (get_other_type () == view_listing
)
206 vfs_stamp_path (other_panel
->cwd
);
211 /* Compare two timeval structures. Return 0 is t1 is less than t2. */
213 timeoutcmp (struct timeval
*t1
, struct timeval
*t2
)
215 return ((t1
->tv_sec
< t2
->tv_sec
)
216 || ((t1
->tv_sec
== t2
->tv_sec
)
217 && (t1
->tv_usec
<= t2
->tv_usec
)));
221 /* This is called from timeout handler with now = 0, or can be called
222 with now = 1 to force freeing all filesystems that are not in use */
226 static int locked
= 0;
228 struct vfs_stamping
*stamp
, *st
;
230 /* Avoid recursive invocation, e.g. when one of the free functions
236 gettimeofday (&time
, NULL
);
237 time
.tv_sec
-= vfs_timeout
;
239 for (stamp
= stamps
; stamp
!= NULL
;) {
240 if (now
|| (timeoutcmp (&stamp
->time
, &time
))) {
243 (*stamp
->v
->free
) (stamp
->id
);
244 vfs_rmstamp (stamp
->v
, stamp
->id
);
254 * Return the number of seconds remaining to the vfs timeout.
255 * FIXME: The code should be improved to actually return the number of
256 * seconds until the next item times out.
261 return stamps
? 10 : 0;
266 vfs_timeout_handler (void)
273 vfs_release_path (const char *dir
)
275 struct vfs_class
*oldvfs
;
278 oldvfs
= vfs_get_class (dir
);
279 oldvfsid
= vfs_getid (oldvfs
, dir
);
280 vfs_stamp_create (oldvfs
, oldvfsid
);
288 struct vfs_stamping
*stamp
, *st
;
290 for (stamp
= stamps
, stamps
= 0; stamp
!= NULL
;) {
292 (*stamp
->v
->free
) (stamp
->id
);
299 vfs_rmstamp (stamps
->v
, stamps
->id
);