+2004-10-22 Ken Raeburn <raeburn@mit.edu>
+
+ * prof_file.c (profile_update_file_data): When resetting flags,
+ preserve SHARED flag.
+ (scan_shared_trees_locked, scan_shared_trees_unlocked): Convert to
+ macros, so line numbers reported by assert will be useful.
+ * prof_test1 (test2): Run new test of modifications with other
+ existing open profile handles.
+
2004-10-19 Ken Raeburn <raeburn@mit.edu>
* libprofile.exports: Add profile_flush_to_file.
static void profile_free_file_data(prf_data_t);
-static void scan_shared_trees_locked(void)
-{
- prf_data_t d;
- k5_mutex_assert_locked(&g_shared_trees_mutex);
- for (d = g_shared_trees; d; d = d->next) {
- assert(d->magic == PROF_MAGIC_FILE_DATA);
- assert((d->flags & PROFILE_FILE_SHARED) != 0);
- assert(d->filespec[0] != 0);
- assert(d->fslen <= 1000); /* XXX */
- assert(d->filespec[d->fslen] == 0);
- assert(d->fslen = strlen(d->filespec));
- }
-}
+#define scan_shared_trees_locked() \
+ { \
+ prf_data_t d; \
+ k5_mutex_assert_locked(&g_shared_trees_mutex); \
+ for (d = g_shared_trees; d; d = d->next) { \
+ assert(d->magic == PROF_MAGIC_FILE_DATA); \
+ assert((d->flags & PROFILE_FILE_SHARED) != 0); \
+ assert(d->filespec[0] != 0); \
+ assert(d->fslen <= 1000); /* XXX */ \
+ assert(d->filespec[d->fslen] == 0); \
+ assert(d->fslen = strlen(d->filespec)); \
+ } \
+ }
-static void scan_shared_trees_unlocked(void)
-{
- int r;
- r = k5_mutex_lock(&g_shared_trees_mutex);
- assert (r == 0);
- scan_shared_trees_locked();
- k5_mutex_unlock(&g_shared_trees_mutex);
-}
+#define scan_shared_trees_unlocked() \
+ { \
+ int r; \
+ r = k5_mutex_lock(&g_shared_trees_mutex); \
+ assert (r == 0); \
+ scan_shared_trees_locked(); \
+ k5_mutex_unlock(&g_shared_trees_mutex); \
+ }
static int rw_access(const_profile_filespec_t filespec)
{
return retval;
}
data->upd_serial++;
- data->flags = 0;
+ data->flags &= PROFILE_FILE_SHARED;
if (rw_access(data->filespec))
data->flags |= PROFILE_FILE_RW;
retval = profile_parse_file(f, &data->root);
set wd [pwd]
-set p [profile_init_path $wd/test2.ini]
set verbose 0
proc test1 {} {
- global wd p verbose
+ global wd verbose
+ set p [profile_init_path $wd/test2.ini]
set sect {{test section 1} child_section child}
set iter [profile_iterator_create $p $sect 0]
set done 0
puts stderr "Error: Deleting in iterator didn't get them all."
exit 1
} else {
- puts "OK: Deleting in iteration got rid of all entries."
+ puts "OK: test1: Deleting in iteration got rid of all entries."
}
}
+proc test2 {} {
+ global wd verbose
+
+ # lxs said: create A, read A, flush A, read A, create B, read B, crash
+ # (where "create" refers to the object, not the file)
+
+ if $verbose { puts "Running test2" }
+ set c [profile_init_path $wd/test2.ini]
+ # create A
+ set a [profile_init_path $wd/test2.ini]
+ if $verbose { puts "Opened profile $wd/test2.ini" }
+ # read A
+ set x [profile_get_values $a {{test section 1} foo}]
+ if $verbose { puts "Read $x from profile" }
+ if $verbose { puts "updating" }
+ exec sleep 2
+ profile_update_relation $a {{test section 1} foo} [lindex $x 0] [lindex $x 0]
+ set x [profile_get_values $a {{test section 1} foo}]
+ if $verbose { puts "Read $x from profile" }
+ # flush A
+ profile_flush $a
+ # read A again
+ set x [profile_get_values $a {{test section 1} foo}]
+ if $verbose { puts "Read $x from profile" }
+ profile_release $a
+ # create B
+ set b [profile_init_path $wd/test2.ini]
+ if $verbose { puts "Opened profile again" }
+ # read B
+ set x [profile_get_values $b {{test section 1} foo}]
+ if $verbose { puts "Read $x from profile" }
+ # read B
+ set x [profile_get_values $b {{test section 1} foo}]
+ if $verbose { puts "Read $x from profile" }
+ # If we got this far, now what?
+ profile_release $b
+ profile_release $c
+ puts "OK: test2: Modifications don't corrupt existing open handles"
+}
+
test1
+test2
exit 0