diff --git a/lib/vfs/gc.c b/lib/vfs/gc.c index fea95a34f..c71dc14c1 100644 --- a/lib/vfs/gc.c +++ b/lib/vfs/gc.c @@ -109,8 +109,8 @@ static GSList *stamps = NULL; /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ -/** Compare two timeval structures. Return 0 is t1 is less than t2. */ -static inline int +/** Compare two timeval structures. Return TRUE is t1 is less than t2. */ +static gboolean timeoutcmp (const struct timeval *t1, const struct timeval *t2) { return ((t1->tv_sec < t2->tv_sec) @@ -130,33 +130,6 @@ vfs_stamp_compare (gconstpointer a, gconstpointer b) /* --------------------------------------------------------------------------------------------- */ -static void -vfs_stamp_free (gpointer data, gpointer user_data) -{ - struct vfs_stamping *stamp = VFS_STAMPING (data); - - (void) user_data; - - if (stamp->v->free != NULL) - stamp->v->free (stamp->id); -} - -/* --------------------------------------------------------------------------------------------- */ - -static void -vfs_stamp_expire (gpointer data, gpointer user_data) -{ - struct vfs_stamping *stamp = VFS_STAMPING (data); - - if (user_data == NULL || timeoutcmp (&(stamp->time), (struct timeval *) user_data) != 0) - { - vfs_stamp_free (data, NULL); - vfs_rmstamp (stamp->v, stamp->id); - } -} - -/* --------------------------------------------------------------------------------------------- */ - static void vfs_addstamp (struct vfs_class *v, vfsid id) { @@ -269,8 +242,8 @@ vfs_stamp_create (struct vfs_class *vclass, vfsid id) } /* --------------------------------------------------------------------------------------------- */ -/** This is called from timeout handler with now = 0, or can be called - with now = 1 to force freeing all filesystems that are not in use */ +/** This is called from timeout handler with now == FALSE, + or can be called with now == TRUE to force freeing all filesystems */ void vfs_expire (gboolean now) @@ -281,19 +254,48 @@ vfs_expire (gboolean now) calls message */ if (locked) return; - locked = TRUE; if (now) - g_slist_foreach (stamps, vfs_stamp_expire, NULL); + { + /* reverse list to free nested VFSes at first */ + stamps = g_slist_reverse (stamps); + + while (stamps != NULL) + { + struct vfs_stamping *stamping = VFS_STAMPING (stamps->data); + + if (stamping->v->free != NULL) + stamping->v->free (stamping->id); + g_free (stamping); + stamps = g_slist_delete_link (stamps, stamps); + } + } else { struct timeval lc_time; + GSList *stamp; gettimeofday (&lc_time, NULL); lc_time.tv_sec -= vfs_timeout; - g_slist_foreach (stamps, vfs_stamp_expire, &lc_time); + for (stamp = stamps; stamp != NULL;) + { + struct vfs_stamping *stamping = VFS_STAMPING (stamp->data); + + if (!timeoutcmp (&stamping->time, &lc_time)) + stamp = g_slist_next (stamp); + else + { + GSList *st; + + st = g_slist_next (stamp); + if (stamping->v->free != NULL) + stamping->v->free (stamping->id); + vfs_rmstamp (stamping->v, stamping->id); + stamp = st; + } + } } locked = FALSE; @@ -337,9 +339,7 @@ vfs_release_path (const vfs_path_t * vpath) void vfs_gc_done (void) { - g_slist_foreach (stamps, vfs_stamp_free, NULL); - g_slist_free_full (stamps, g_free); - stamps = NULL; + vfs_expire (TRUE); } /* --------------------------------------------------------------------------------------------- */