Browse Source

Ticket #4147: VFS timestamps: use g_get_real_time().

In the function vfs_expire(), curr_time and exp_time are declared
guint64. curr_time is initialised with a timestamp and exp_time
with this timestamp minus vfs_timeout seconds. Later there is if
(stamping->time <= exp_time). Prior to commit
a94dd7d2ded0dd3ce3f6cd2c56612327d065b5ac curr_time was initialised with
a value larger than vfs_timeout seconds, so everything was fine. This
commit changed the initialisation to a timer starting when mc is
started. So for the first vfs_timeout seconds, the result of the
subtraction is negative, but it is a guint64, so we just get a VERY
large unsigned value and the if (stamping->time <= exp_time) is always
true. So mc thinks the vfs hasn't been used recently and goes into an
infinite loop.

If one opens a .rpm file with mc and goes into the CONTENTS.cpio and
then tries to go into the .tar.gz there (this is the usual structure of
a .rpm) after waiting vfs_timeout seconds, everything is fine. However,
before vfs_timeout seconds, mc hangs.

Solution: use g_get_real_time() instead of mc_timer_elapsed().

Thanks nvwarr at hotmail.com for finding out the reason for this bug.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Andrew Borodin 4 years ago
parent
commit
4a83daacc4
5 changed files with 14 additions and 18 deletions
  1. 2 3
      lib/vfs/direntry.c
  2. 5 6
      lib/vfs/gc.c
  3. 1 1
      lib/vfs/xdirentry.h
  4. 1 2
      src/vfs/fish/fish.c
  5. 5 6
      src/vfs/ftpfs/ftpfs.c

+ 2 - 3
lib/vfs/direntry.c

@@ -70,7 +70,6 @@
 
 #include "lib/tty/tty.h"        /* enable/disable interrupt key */
 #include "lib/util.h"           /* custom_canonicalize_pathname() */
-#include "lib/timer.h"
 #if 0
 #include "lib/widget.h"         /* message() */
 #endif
@@ -863,7 +862,7 @@ vfs_s_free (vfsid id)
 static gboolean
 vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino)
 {
-    guint64 tim;
+    gint64 tim;
 
     if (me->flush)
     {
@@ -871,7 +870,7 @@ vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino)
         return 0;
     }
 
-    tim = mc_timer_elapsed (mc_global.timer);
+    tim = g_get_real_time ();
 
     return (tim < ino->timestamp);
 }

+ 5 - 6
lib/vfs/gc.c

@@ -44,7 +44,6 @@
 #include "lib/global.h"
 #include "lib/event.h"
 #include "lib/util.h"           /* MC_PTR_FREE */
-#include "lib/timer.h"
 
 #include "vfs.h"
 #include "utilvfs.h"
@@ -98,7 +97,7 @@ struct vfs_stamping
 {
     struct vfs_class *v;
     vfsid id;
-    guint64 time;
+    gint64 time;
 };
 
 /*** file scope variables ************************************************************************/
@@ -130,7 +129,7 @@ vfs_addstamp (struct vfs_class *v, vfsid id)
         stamp = g_new (struct vfs_stamping, 1);
         stamp->v = v;
         stamp->id = id;
-        stamp->time = mc_timer_elapsed (mc_global.timer);
+        stamp->time = g_get_real_time ();
 
         stamps = g_slist_append (stamps, stamp);
     }
@@ -153,7 +152,7 @@ vfs_stamp (struct vfs_class *v, vfsid id)
     stamp = g_slist_find_custom (stamps, &what, vfs_stamp_compare);
     if (stamp != NULL && stamp->data != NULL)
     {
-        VFS_STAMPING (stamp->data)->time = mc_timer_elapsed (mc_global.timer);
+        VFS_STAMPING (stamp->data)->time = g_get_real_time ();
         ret = TRUE;
     }
 
@@ -239,7 +238,7 @@ void
 vfs_expire (gboolean now)
 {
     static gboolean locked = FALSE;
-    guint64 curr_time, exp_time;
+    gint64 curr_time, exp_time;
     GSList *stamp;
 
     /* Avoid recursive invocation, e.g. when one of the free functions
@@ -248,7 +247,7 @@ vfs_expire (gboolean now)
         return;
     locked = TRUE;
 
-    curr_time = mc_timer_elapsed (mc_global.timer);
+    curr_time = g_get_real_time ();
     exp_time = curr_time - vfs_timeout * G_USEC_PER_SEC;
 
     if (now)

+ 1 - 1
lib/vfs/xdirentry.h

@@ -91,7 +91,7 @@ struct vfs_s_inode
     struct stat st;             /* Parameters of this inode */
     char *linkname;             /* Symlink's contents */
     char *localname;            /* Filename of local file, if we have one */
-    guint64 timestamp;          /* Subclass specific */
+    gint64 timestamp;           /* Subclass specific */
     off_t data_offset;          /* Subclass specific */
 };
 

+ 1 - 2
src/vfs/fish/fish.c

@@ -65,7 +65,6 @@
 #include "lib/fileloc.h"
 #include "lib/util.h"           /* my_exit() */
 #include "lib/mcconfig.h"
-#include "lib/timer.h"
 
 #include "src/execute.h"        /* pre_exec, post_exec */
 
@@ -766,7 +765,7 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
 
     vfs_print_message (_("fish: Reading directory %s..."), remote_path);
 
-    dir->timestamp = mc_timer_elapsed (mc_global.timer) + fish_directory_timeout * G_USEC_PER_SEC;
+    dir->timestamp = g_get_real_time () + fish_directory_timeout * G_USEC_PER_SEC;
 
     quoted_path = strutils_shell_escape (remote_path);
     (void) fish_command_v (me, super, NONE, FISH_SUPER (super)->scr_ls, "FISH_FILENAME=%s;\n",

+ 5 - 6
src/vfs/ftpfs/ftpfs.c

@@ -98,7 +98,6 @@ What to do with this?
 #include "lib/util.h"
 #include "lib/strutil.h"        /* str_move() */
 #include "lib/mcconfig.h"
-#include "lib/timer.h"
 
 #include "lib/tty/tty.h"        /* enable/disable interrupt key */
 #include "lib/widget.h"         /* message() */
@@ -1491,17 +1490,17 @@ ftpfs_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
 
         if (select (dsock + 1, &mask, NULL, NULL, NULL) > 0)
         {
-            guint64 start_tim;
+            gint64 start_tim;
             char buf[BUF_8K];
 
-            start_tim = mc_timer_elapsed (mc_global.timer);
+            start_tim = g_get_real_time ();
 
             /* flush the remaining data */
             while (read (dsock, buf, sizeof (buf)) > 0)
             {
-                guint64 tim;
+                gint64 tim;
 
-                tim = mc_timer_elapsed (mc_global.timer);
+                tim = g_get_real_time ();
 
                 if (tim > start_tim + ABORT_TIMEOUT)
                 {
@@ -1748,7 +1747,7 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path
         return (-1);
     }
 
-    dir->timestamp = mc_timer_elapsed (mc_global.timer) + ftpfs_directory_timeout * G_USEC_PER_SEC;
+    dir->timestamp = g_get_real_time () + ftpfs_directory_timeout * G_USEC_PER_SEC;
 
     if (ftp_super->strict == RFC_STRICT)
         sock = ftpfs_open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0);