From cc823ff1f9ccab035fed4ff424917390ef4abe5b Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sun, 13 Mar 2005 07:34:23 +0000 Subject: [PATCH] profile library should check high-resolution timestamps if available With the current profile code, it's possible for a file to be read when partially written, with the writing of the new file contents being completed within the same 1-second clock value, causing the profile code not to re-read the contents. Using a higher-resolution timestamp, available on many systems now, should help reduce that window. (Checking file sizes should also, consider doing that separately.) * configure.in: Check struct stat for fields st_mtimensec, st_mtimespec.tv_nsec, and st_mtim.tv_usec. * prof_file.c (profile_update_file_data): If one of them is found, use it as the fractional part of the timestamp. Do re-read the file if the fractional parts don't match. * prof_int.h (struct _prf_data_t): Add new field frac_ts. ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17121 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/profile/ChangeLog | 9 +++++++++ src/util/profile/configure.in | 2 ++ src/util/profile/prof_file.c | 15 ++++++++++++++- src/util/profile/prof_int.h | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog index 8208db91c..4063b1722 100644 --- a/src/util/profile/ChangeLog +++ b/src/util/profile/ChangeLog @@ -1,3 +1,12 @@ +2005-03-13 Ken Raeburn + + * configure.in: Check struct stat for fields st_mtimensec, + st_mtimespec.tv_nsec, and st_mtim.tv_usec. + * prof_file.c (profile_update_file_data): If one of them is + found, use it as the fractional part of the timestamp. Do + re-read the file if the fractional parts don't match. + * prof_int.h (struct _prf_data_t): Add new field frac_ts. + 2005-03-03 Ken Raeburn * prof_tree.c (profile_node_iterator): After checking skip_num diff --git a/src/util/profile/configure.in b/src/util/profile/configure.in index 38fb9e426..faae28955 100644 --- a/src/util/profile/configure.in +++ b/src/util/profile/configure.in @@ -6,6 +6,8 @@ AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_HEADERS(unistd.h stdlib.h pwd.h) AC_CHECK_FUNCS(stat access strdup getpwuid_r) +AC_CHECK_MEMBERS([struct stat.st_mtimensec,struct stat.st_mtimespec.tv_nsec,struct stat.st_mtim.tv_usec],,,[#include +#include ]) AC_PROG_AWK AC_KRB5_TCL DO_TCL= diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c index cdeaf50a7..347fef739 100644 --- a/src/util/profile/prof_file.c +++ b/src/util/profile/prof_file.c @@ -316,6 +316,7 @@ errcode_t profile_update_file_data(prf_data_t data) errcode_t retval; #ifdef HAVE_STAT struct stat st; + unsigned long frac; #ifdef STAT_ONCE_PER_SECOND time_t now; #endif @@ -342,7 +343,18 @@ errcode_t profile_update_file_data(prf_data_t data) #ifdef STAT_ONCE_PER_SECOND data->last_stat = now; #endif - if (st.st_mtime == data->timestamp && data->root != NULL) { +#if defined HAVE_STRUCT_STAT_ST_MTIMENSEC + frac = st.st_mtimensec; +#elif defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC + frac = st.st_mtimespec.tv_nsec; +#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + frac = st.st_mtim.tv_usec; +#else + frac = 0; +#endif + if (st.st_mtime == data->timestamp + && frac == data->frac_ts + && data->root != NULL) { k5_mutex_unlock(&data->lock); return 0; } @@ -387,6 +399,7 @@ errcode_t profile_update_file_data(prf_data_t data) assert(data->root != NULL); #ifdef HAVE_STAT data->timestamp = st.st_mtime; + data->frac_ts = frac; #endif k5_mutex_unlock(&data->lock); return 0; diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h index 43d15b0e4..1a56a3f30 100644 --- a/src/util/profile/prof_int.h +++ b/src/util/profile/prof_int.h @@ -42,6 +42,7 @@ struct _prf_data_t { time_t last_stat; #endif time_t timestamp; /* time tree was last updated from file */ + unsigned long frac_ts; /* fractional part of timestamp, if any */ int flags; /* r/w, dirty */ int upd_serial; /* incremented when data changes */ char *comment; -- 2.26.2