This is the mail archive of the
cygwin-developers@cygwin.com
mailing list for the Cygwin project.
[RFA] A kinder, gentler check for /etc/{passwd,group} changes
- To: cygwin-developers at cygwin dot com
- Subject: [RFA] A kinder, gentler check for /etc/{passwd,group} changes
- From: Christopher Faylor <cgf at redhat dot com>
- Date: Sat, 8 Sep 2001 22:51:33 -0400
- Reply-To: cygwin-developers at cygwin dot com
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 ******************************/