profile library should check high-resolution timestamps if available
authorKen Raeburn <raeburn@mit.edu>
Sun, 13 Mar 2005 07:34:23 +0000 (07:34 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sun, 13 Mar 2005 07:34:23 +0000 (07:34 +0000)
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
src/util/profile/configure.in
src/util/profile/prof_file.c
src/util/profile/prof_int.h

index 8208db91c9c094b860189a8ea8e1b13b774be07d..4063b1722b762e34f0cdd2d9c523f2dfb67e9bff 100644 (file)
@@ -1,3 +1,12 @@
+2005-03-13  Ken Raeburn  <raeburn@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * prof_tree.c (profile_node_iterator): After checking skip_num
index 38fb9e426a383bea0b001ff1068b9cf9f44c4ae6..faae289558920d5da13021ab1609c88c716dc126 100644 (file)
@@ -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 <sys/types.h>
+#include <sys/stat.h>])
 AC_PROG_AWK
 AC_KRB5_TCL
 DO_TCL=
index cdeaf50a7704c5c69e3361a2ec5ccfd85bb2b95e..347fef739e2918d120cdd38f43b0fd40e468c841 100644 (file)
@@ -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;
index 43d15b0e44ba5741826b6dd15677073b09c7c4f3..1a56a3f30b9e47abc2ed3334765a14fa5525aa5b 100644 (file)
@@ -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;