This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA] A kinder, gentler check for /etc/{passwd,group} changes


Here's what I did, based on the FindFirstFileChangeNotification ideas.

It seems to get performance back down to around 1.3.2 levels when
combined with a couple of other minor changes.

Now that I see the patch, I realize that the etc_changed function
probably belongs in miscfuncs.cc rather than in dcrt0.cc.

There is a little bit of slop from the malloc synchronization problem
that I mentioned previously.  I realized that it would be trivial to
make fork and malloc play well together, so I added some logic to do
that.  It is not in this patch.  I'm just going to be checking that
in.

The only thing I don't know is if the etc_changed function actually
does anything useful.  I don't have a useful test case for that but
I thought that Corinna might.

Btw, I really like the way that Corinna handled the passwd_state stuff.
It was, IMO, an elegant use of C++.

I wonder if we could generalize the similar code in passwd.cc and grp.cc
into some kind of class for 1.3.4...

cgf

Index: cygheap.h
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/cygheap.h,v
retrieving revision 1.22
diff -p -r1.22 cygheap.h
*** cygheap.h	2001/09/07 21:32:04	1.22
--- cygheap.h	2001/09/09 02:38:35
*************** struct init_cygheap
*** 161,166 ****
--- 161,167 ----
    mode_t umask;
    HANDLE shared_h;
    HANDLE console_h;
+   HANDLE etc_changed_h;
    cwdstuff cwd;
    dtable fdtab;
  };
Index: dcrt0.cc
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.107
diff -p -r1.107 dcrt0.cc
*** dcrt0.cc	2001/09/07 21:32:04	1.107
--- dcrt0.cc	2001/09/09 02:38:36
*************** cygbench (const char *s)
*** 1108,1110 ****
--- 1108,1143 ----
      small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
  }
  #endif
+ 
+ bool
+ etc_changed ()
+ {
+   bool res = 0;
+ 
+   if (!cygheap->etc_changed_h)
+     {
+       path_conv pwd ("/etc");
+       cygheap->etc_changed_h = FindFirstChangeNotification (pwd, FALSE,
+ 					      FILE_NOTIFY_CHANGE_LAST_WRITE);
+       if (cygheap->etc_changed_h == INVALID_HANDLE_VALUE)
+ 	system_printf ("Can't open /etc for checking, %E", (char *) pwd,
+ 	    	       cygheap->etc_changed_h);
+       else if (!DuplicateHandle (hMainProc, cygheap->etc_changed_h, hMainProc,
+ 	    			 &cygheap->etc_changed_h, 0, TRUE,
+ 				 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+ 	{
+ 	  system_printf ("Can't inherit /etc handle, %E", (char *) pwd,
+ 	      		 cygheap->etc_changed_h);
+ 	  cygheap->etc_changed_h = INVALID_HANDLE_VALUE;
+ 	}
+     }
+ 
+    if (cygheap->etc_changed_h != INVALID_HANDLE_VALUE
+        && WaitForSingleObject (cygheap->etc_changed_h, 0) == WAIT_OBJECT_0)
+      {
+        (void) FindNextChangeNotification (cygheap->etc_changed_h);
+        res = 1;
+      }
+ 
+   return res;
+ }
Index: grp.cc
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/grp.cc,v
retrieving revision 1.29
diff -p -r1.29 grp.cc
*** grp.cc	2001/09/07 21:32:04	1.29
--- grp.cc	2001/09/09 02:38:36
*************** enum grp_state {
*** 54,73 ****
  };
  class grp_check {
    grp_state state;
-   FILETIME  last_modified;
    char	    grp_w32[MAX_PATH];
  
  public:
    grp_check () : state (uninitialized)
      {
-       last_modified.dwLowDateTime = last_modified.dwHighDateTime = 0;
        grp_w32[0] = '\0';
      }
    operator grp_state ()
      {
-       HANDLE h;
-       WIN32_FIND_DATA data;
- 
        if (!grp_w32[0])	/* First call. */
  	{
  	  path_conv g ("/etc/group", PC_SYM_FOLLOW | PC_FULL);
--- 54,68 ----
*************** public:
*** 75,89 ****
  	    strcpy (grp_w32, g.get_win32 ());
  	}
  
!       if ((h = FindFirstFile (grp_w32, &data)) != INVALID_HANDLE_VALUE)
! 	{
! 	  if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0)
! 	    {
! 	      state = uninitialized;
! 	      last_modified = data.ftLastWriteTime;
! 	    }
! 	  FindClose (h);
! 	}
        return state;
      }
    void operator = (grp_state nstate)
--- 70,77 ----
  	    strcpy (grp_w32, g.get_win32 ());
  	}
  
!       if (etc_changed ())
! 	state = uninitialized;
        return state;
      }
    void operator = (grp_state nstate)
Index: passwd.cc
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/passwd.cc,v
retrieving revision 1.31
diff -p -r1.31 passwd.cc
*** passwd.cc	2001/09/07 21:32:04	1.31
--- passwd.cc	2001/09/09 02:44:13
*************** enum pwd_state {
*** 43,78 ****
  };
  class pwd_check {
    pwd_state state;
-   FILETIME  last_modified;
    char	    pwd_w32[MAX_PATH];
  
  public:
    pwd_check () : state (uninitialized)
      {
-       last_modified.dwLowDateTime = last_modified.dwHighDateTime = 0;
        pwd_w32[0] = '\0';
      }
    operator pwd_state ()
      {
-       HANDLE h;
-       WIN32_FIND_DATA data;
- 
        if (!pwd_w32[0])	/* First call. */
  	{
  	  path_conv p ("/etc/passwd", PC_SYM_FOLLOW | PC_FULL);
  	  if (!p.error)
! 	    strcpy (pwd_w32, p.get_win32 ());
! 	}
! 
!       if ((h = FindFirstFile (pwd_w32, &data)) != INVALID_HANDLE_VALUE)
! 	{
! 	  if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0)
! 	    {
! 	      state = uninitialized;
! 	      last_modified = data.ftLastWriteTime;
! 	    }
! 	  FindClose (h);
  	}
        return state;
      }
    void operator = (pwd_state nstate)
--- 43,65 ----
  };
  class pwd_check {
    pwd_state state;
    char	    pwd_w32[MAX_PATH];
  
  public:
    pwd_check () : state (uninitialized)
      {
        pwd_w32[0] = '\0';
      }
    operator pwd_state ()
      {
        if (!pwd_w32[0])	/* First call. */
  	{
  	  path_conv p ("/etc/passwd", PC_SYM_FOLLOW | PC_FULL);
  	  if (!p.error)
! 	    strcpy (pwd_w32, p);
  	}
+       if (etc_changed ())
+ 	state = uninitialized;
        return state;
      }
    void operator = (pwd_state nstate)
Index: winsup.h
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/winsup.h,v
retrieving revision 1.66
diff -p -r1.66 winsup.h
*** winsup.h	2001/09/06 05:17:22	1.66
--- winsup.h	2001/09/09 02:38:37
*************** extern bool wsock_started;
*** 210,215 ****
--- 211,220 ----
  extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));
  extern "C" int __small_sprintf (char *dst, const char *fmt, ...) /*__attribute__ ((regparm (2)))*/;
  extern "C" int __small_vsprintf (char *dst, const char *fmt, va_list ap) /*__attribute__ ((regparm (3)))*/;
+ 
+ extern "C" void __malloc_lock (struct _reent *);
+ extern "C" void __malloc_unlock (struct _reent *);
+ bool etc_changed ();
  
  /**************************** Exports ******************************/
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]