emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r110520: Fix bug #12587 with slow sta


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110520: Fix bug #12587 with slow startup on MS-Windows with Netlogon service.
Date: Fri, 12 Oct 2012 17:19:54 +0200
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110520
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Fri 2012-10-12 17:19:54 +0200
message:
  Fix bug #12587 with slow startup on MS-Windows with Netlogon service.
  
   src/fileio.c (check_existing): New function.
   (make_temp_name, Ffile_exists_p, Ffile_writable_p): Call it
   instead of calling 'stat', when what's needed is to check whether
   a file exists.  This avoids expensive system calls on MS-Windows.
   src/w32.c (init_environment): Call 'check_existing' instead of 'stat'.
   src/lread.c (openp) [WINDOWSNT]: Call 'access' instead of 'stat' to
   determine whether a file exists and is not a directory.
   src/lisp.h (check_existing): Add prototype.
modified:
  src/ChangeLog
  src/fileio.c
  src/lisp.h
  src/lread.c
  src/w32.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-10-12 10:01:05 +0000
+++ b/src/ChangeLog     2012-10-12 15:19:54 +0000
@@ -1,3 +1,19 @@
+2012-10-12  Eli Zaretskii  <address@hidden>
+
+       * fileio.c (check_existing): New function.
+       (make_temp_name, Ffile_exists_p, Ffile_writable_p): Call it
+       instead of calling 'stat', when what's needed is to check whether
+       a file exists.  This avoids expensive system calls on MS-Windows.
+       (Bug#12587)
+
+       * w32.c (init_environment): Call 'check_existing' instead of
+       'stat'.
+
+       * lread.c (openp) [WINDOWSNT]: Call 'access' instead of 'stat' to
+       determine whether a file exists and is not a directory.
+
+       * lisp.h (check_existing): Add prototype.
+
 2012-10-12  Jan Djärv  <address@hidden>
 
        * nsfont.m (nsfont_open): Remove font cache, it is not GC correct.

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2012-10-05 09:17:17 +0000
+++ b/src/fileio.c      2012-10-12 15:19:54 +0000
@@ -52,6 +52,7 @@
 #define NOMINMAX 1
 #include <windows.h>
 #include <fcntl.h>
+#include <sys/file.h>
 #endif /* not WINDOWSNT */
 
 #ifdef MSDOS
@@ -668,7 +669,6 @@
 
   while (1)
     {
-      struct stat ignored;
       unsigned num = make_temp_name_count;
 
       p[0] = make_temp_name_tbl[num & 63], num >>= 6;
@@ -680,7 +680,7 @@
       make_temp_name_count += 25229;
       make_temp_name_count %= 225307;
 
-      if (stat (data, &ignored) < 0)
+      if (!check_existing (data))
        {
          /* We want to return only if errno is ENOENT.  */
          if (errno == ENOENT)
@@ -2423,6 +2423,21 @@
   return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil;
 }
 
+/* Return true if FILENAME exists.  */
+bool
+check_existing (const char *filename)
+{
+#ifdef DOS_NT
+  /* The full emulation of Posix 'stat' is too expensive on
+     DOS/Windows, when all we want to know is whether the file exists.
+     So we use 'access' instead, which is much more lightweight.  */
+  return (access (filename, F_OK) >= 0);
+#else
+  struct stat st;
+  return (stat (filename, &st) >= 0);
+#endif
+}
+
 /* Return true if file FILENAME exists and can be executed.  */
 
 static bool
@@ -2490,7 +2505,6 @@
 {
   Lisp_Object absname;
   Lisp_Object handler;
-  struct stat statbuf;
 
   CHECK_STRING (filename);
   absname = Fexpand_file_name (filename, Qnil);
@@ -2503,7 +2517,7 @@
 
   absname = ENCODE_FILE (absname);
 
-  return (stat (SSDATA (absname), &statbuf) >= 0) ? Qt : Qnil;
+  return (check_existing (SSDATA (absname))) ? Qt : Qnil;
 }
 
 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
@@ -2584,7 +2598,6 @@
 {
   Lisp_Object absname, dir, encoded;
   Lisp_Object handler;
-  struct stat statbuf;
 
   CHECK_STRING (filename);
   absname = Fexpand_file_name (filename, Qnil);
@@ -2596,7 +2609,7 @@
     return call2 (handler, Qfile_writable_p, absname);
 
   encoded = ENCODE_FILE (absname);
-  if (stat (SSDATA (encoded), &statbuf) >= 0)
+  if (check_existing (SSDATA (encoded)))
     return (check_writable (SSDATA (encoded))
            ? Qt : Qnil);
 
@@ -2611,9 +2624,7 @@
   /* The read-only attribute of the parent directory doesn't affect
      whether a file or directory can be created within it.  Some day we
      should check ACLs though, which do affect this.  */
-  if (stat (SDATA (dir), &statbuf) < 0)
-    return Qnil;
-  return S_ISDIR (statbuf.st_mode) ? Qt : Qnil;
+  return (access (SDATA (dir), D_OK) < 0) ? Qnil : Qt;
 #else
   return (check_writable (!NILP (dir) ? SSDATA (dir) : "")
          ? Qt : Qnil);

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2012-10-11 16:23:37 +0000
+++ b/src/lisp.h        2012-10-12 15:19:54 +0000
@@ -3182,6 +3182,7 @@
 extern void syms_of_fileio (void);
 extern Lisp_Object make_temp_name (Lisp_Object, bool);
 extern Lisp_Object Qdelete_file;
+extern bool check_existing (const char *);
 
 /* Defined in search.c.  */
 extern void shrink_regexp_cache (void);

=== modified file 'src/lread.c'
--- a/src/lread.c       2012-10-11 16:23:37 +0000
+++ b/src/lread.c       2012-10-12 15:19:54 +0000
@@ -1449,7 +1449,6 @@
   bool absolute = 0;
   ptrdiff_t want_length;
   Lisp_Object filename;
-  struct stat st;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
   Lisp_Object string, tail, encoded_fn;
   ptrdiff_t max_suffix_len = 0;
@@ -1543,11 +1542,18 @@
            }
          else
            {
+#ifndef WINDOWSNT
+             struct stat st;
+#endif
              const char *pfn;
 
              encoded_fn = ENCODE_FILE (string);
              pfn = SSDATA (encoded_fn);
+#ifdef WINDOWSNT
+             exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0;
+#else
              exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode));
+#endif
              if (exists)
                {
                  /* Check that we can access or open it.  */

=== modified file 'src/w32.c'
--- a/src/w32.c 2012-10-08 12:53:18 +0000
+++ b/src/w32.c 2012-10-12 15:19:54 +0000
@@ -1612,7 +1612,6 @@
     LPBYTE lpval;
     DWORD dwType;
     char locale_name[32];
-    struct stat ignored;
     char default_home[MAX_PATH];
     int appdata = 0;
 
@@ -1653,7 +1652,7 @@
     /* For backwards compatibility, check if a .emacs file exists in C:/
        If not, then we can try to default to the appdata directory under the
        user's profile, which is more likely to be writable.   */
-    if (stat ("C:/.emacs", &ignored) < 0)
+    if (check_existing ("C:/.emacs"))
       {
        HRESULT profile_result;
        /* Dynamically load ShGetFolderPath, as it won't exist on versions


reply via email to

[Prev in Thread] Current Thread [Next in Thread]