Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Sat, 8 Sep 2001 22:51:33 -0400 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: [RFA] A kinder, gentler check for /etc/{passwd,group} changes Message-ID: <20010908225133.A17336@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.21i 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 ******************************/