summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2002-12-20 22:38:04 +0000
committerKen Raeburn <raeburn@mit.edu>2002-12-20 22:38:04 +0000
commit7c28091d5daeb6431e6e76aeeca9ba1d33665d66 (patch)
treebe6b961a9753ec8941509c03fa7c16fbbeabf4d9 /src
parent100ac673adeb87a48fa1deb2cff348af36a1c103 (diff)
downloadkrb5-7c28091d5daeb6431e6e76aeeca9ba1d33665d66.tar.gz
krb5-7c28091d5daeb6431e6e76aeeca9ba1d33665d66.tar.xz
krb5-7c28091d5daeb6431e6e76aeeca9ba1d33665d66.zip
Merge in data tree sharing, minus locking support, plus a bugfix or two
* prof_int.h (SHARE_TREE_DATA): Define. (struct _prf_file_t) [SHARE_TREE_DATA]: Make data field a pointer rather than an array. (struct global_shared_profile_data): New type, for profile library global data. (krb5int_profile_shared_data): Declare new variable. (g_shared_trees): New macro, refers to a field in the global data. (PROFILE_FILE_SHARED): New flag macro. * prof_file.c (krb5int_profile_shared_data): Initialize here. (profile_open_file) [SHARE_TREE_DATA]: Scan g_shared_trees for an entry with the same filename. If found, increment its reference count, update it, and return it; otherwise, allocate a new one, and add it to the list after filling it in. (profile_dereference_data): New function. Decrement reference count if SHARE_TREE_DATA, and free the data if appropriate. (profile_free_file): Call profile_dereference_data. (profile_free_file_data) [SHARE_TREE_DATA]: If the SHARED flag is set, remove it from the g_shared_trees list before freeing. Free up the allocated space. * prof_set.c (rw_setup) [SHARE_TREE_DATA]: If the object's data is shared, copy it into a new data structure not in the global shared list, and dereference the old one. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15060 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/util/profile/ChangeLog25
-rw-r--r--src/util/profile/prof_file.c84
-rw-r--r--src/util/profile/prof_int.h16
-rw-r--r--src/util/profile/prof_set.c36
4 files changed, 152 insertions, 9 deletions
diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog
index cf7c5360f2..bcf9c2f106 100644
--- a/src/util/profile/ChangeLog
+++ b/src/util/profile/ChangeLog
@@ -1,3 +1,28 @@
+2002-12-20 Ken Raeburn <raeburn@mit.edu>
+
+ * prof_int.h (SHARE_TREE_DATA): Define.
+ (struct _prf_file_t) [SHARE_TREE_DATA]: Make data field a pointer
+ rather than an array.
+ (struct global_shared_profile_data): New type, for profile library
+ global data.
+ (krb5int_profile_shared_data): Declare new variable.
+ (g_shared_trees): New macro, refers to a field in the global data.
+ (PROFILE_FILE_SHARED): New flag macro.
+ * prof_file.c (krb5int_profile_shared_data): Initialize here.
+ (profile_open_file) [SHARE_TREE_DATA]: Scan g_shared_trees for an
+ entry with the same filename. If found, increment its reference
+ count, update it, and return it; otherwise, allocate a new one,
+ and add it to the list after filling it in.
+ (profile_dereference_data): New function. Decrement reference
+ count if SHARE_TREE_DATA, and free the data if appropriate.
+ (profile_free_file): Call profile_dereference_data.
+ (profile_free_file_data) [SHARE_TREE_DATA]: If the SHARED flag is
+ set, remove it from the g_shared_trees list before freeing. Free
+ up the allocated space.
+ * prof_set.c (rw_setup) [SHARE_TREE_DATA]: If the object's data is
+ shared, copy it into a new data structure not in the global shared
+ list, and dereference the old one.
+
2002-12-06 Ken Raeburn <raeburn@mit.edu>
* prof_int.h: Include Mac OS X versions of header files if
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
index 4ffe7e1384..e9da626e3d 100644
--- a/src/util/profile/prof_file.c
+++ b/src/util/profile/prof_file.c
@@ -28,13 +28,18 @@
#define stat _stat
#endif
+#ifdef SHARE_TREE_DATA
+struct global_shared_profile_data krb5int_profile_shared_data = {
+ 0
+};
+#endif
+
#ifndef PROFILE_USES_PATHS
#include <FSp_fopen.h>
static OSErr GetMacOSTempFilespec (
const FSSpec* inFilespec,
FSSpec* outFilespec);
-
#endif
static int rw_access(filespec)
@@ -80,7 +85,36 @@ errcode_t profile_open_file(filespec, ret_prof)
if (!prf)
return ENOMEM;
memset(prf, 0, sizeof(struct _prf_file_t));
+ prf->magic = PROF_MAGIC_FILE;
+
+#ifdef SHARE_TREE_DATA
+ for (data = g_shared_trees; data; data = data->next) {
+ if (!strcmp(data->filespec, filespec)
+ /* Check that current uid has read access. */
+ && access(data->filespec, R_OK) == 0)
+ break;
+ }
+ if (data) {
+ retval = profile_update_file_data(data);
+ data->refcount++;
+ prf->data = data;
+ *ret_prof = prf;
+ return retval;
+ }
+ data = malloc(sizeof(struct _prf_data_t));
+ if (data == NULL) {
+ free(prf);
+ return ENOMEM;
+ }
+ memset(data, 0, sizeof(*data));
+ prf->data = data;
+#else
data = prf->data;
+#endif
+
+ data->magic = PROF_MAGIC_FILE_DATA;
+ data->refcount = 1;
+ data->comment = 0;
len = strlen(filespec)+1;
if (filespec[0] == '~' && filespec[1] == '/') {
@@ -98,9 +132,6 @@ errcode_t profile_open_file(filespec, ret_prof)
strcat(data->filespec, filespec+1);
} else
strcpy(data->filespec, filespec);
- prf->magic = PROF_MAGIC_FILE;
- data->magic = PROF_MAGIC_FILE_DATA;
- data->refcount = 1;
retval = profile_update_file(prf);
if (retval) {
@@ -108,6 +139,12 @@ errcode_t profile_open_file(filespec, ret_prof)
return retval;
}
+#ifdef SHARE_TREE_DATA
+ data->next = g_shared_trees;
+ data->flags |= PROFILE_FILE_SHARED;
+ g_shared_trees = data;
+#endif
+
*ret_prof = prf;
return 0;
}
@@ -276,16 +313,47 @@ errout:
}
+void profile_dereference_data(prf_data_t data)
+{
+#ifdef SHARE_TREE_DATA
+ data->refcount--;
+ if (data->refcount == 0)
+ profile_free_file_data(data);
+#else
+ profile_free_file_data(data);
+#endif
+}
+
void profile_free_file(prf)
prf_file_t prf;
{
- profile_free_file_data(prf->data);
- free(prf);
+ profile_dereference_data(prf->data);
+ free(prf);
}
void profile_free_file_data(data)
prf_data_t data;
{
+#ifdef SHARE_TREE_DATA
+ if (data->flags & PROFILE_FILE_SHARED) {
+ /* Remove from linked list. */
+ if (g_shared_trees == data)
+ g_shared_trees = data->next;
+ else {
+ prf_data_t prev, next;
+ prev = g_shared_trees;
+ next = prev->next;
+ while (next) {
+ if (next == data) {
+ prev->next = next->next;
+ break;
+ }
+ prev = next;
+ next = next->next;
+ }
+ }
+ }
+#endif
#ifdef PROFILE_USES_PATHS
if (data->filespec)
free(data->filespec);
@@ -295,6 +363,9 @@ void profile_free_file_data(data)
if (data->comment)
free(data->comment);
data->magic = 0;
+#ifdef SHARE_TREE_DATA
+ free(data);
+#endif
}
errcode_t profile_close_file(prf)
@@ -308,4 +379,3 @@ errcode_t profile_close_file(prf)
profile_free_file(prf);
return 0;
}
-
diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h
index 00fd2847b1..ead23dc3a2 100644
--- a/src/util/profile/prof_int.h
+++ b/src/util/profile/prof_int.h
@@ -30,6 +30,8 @@
typedef long prf_magic_t;
+#define SHARE_TREE_DATA
+
/*
* This is the structure which stores the profile information for a
* particular configuration file.
@@ -50,17 +52,31 @@ typedef struct _prf_data_t *prf_data_t;
struct _prf_file_t {
prf_magic_t magic;
+#ifdef SHARE_TREE_DATA
+ struct _prf_data_t *data;
+#else
struct _prf_data_t data[1];
+#endif
struct _prf_file_t *next;
};
typedef struct _prf_file_t *prf_file_t;
+#ifdef SHARE_TREE_DATA
+struct global_shared_profile_data {
+ /* This is the head of the global list of shared trees */
+ prf_data_t trees;
+};
+extern struct global_shared_profile_data krb5int_profile_shared_data;
+#define g_shared_trees (krb5int_profile_shared_data.trees)
+#endif /* SHARE_TREE_DATA */
+
/*
* The profile flags
*/
#define PROFILE_FILE_RW 0x0001
#define PROFILE_FILE_DIRTY 0x0002
+#define PROFILE_FILE_SHARED 0x0004
/*
* This structure defines the high-level, user visible profile_t
diff --git a/src/util/profile/prof_set.c b/src/util/profile/prof_set.c
index 4c6ccb29d5..5abf5ec9af 100644
--- a/src/util/profile/prof_set.c
+++ b/src/util/profile/prof_set.c
@@ -24,7 +24,7 @@ static errcode_t rw_setup(profile)
profile_t profile;
{
prf_file_t file;
- errcode_t retval;
+ errcode_t retval = 0;
if (!profile)
return PROF_NO_PROFILE;
@@ -39,7 +39,39 @@ static errcode_t rw_setup(profile)
/* Don't update the file if we've already made modifications */
if (file->data->flags & PROFILE_FILE_DIRTY)
return 0;
-
+
+#ifdef SHARE_TREE_DATA
+ if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
+ prf_data_t new_data;
+ new_data = malloc(sizeof(struct _prf_data_t));
+ if (new_data == NULL) {
+ retval = ENOMEM;
+ } else {
+ *new_data = *file->data;
+ /* We can blow away the information because update
+ will be called further down */
+ new_data->comment = NULL;
+ new_data->root = NULL;
+ new_data->flags &= ~PROFILE_FILE_SHARED;
+ new_data->timestamp = 0;
+ /* copy the file spec */
+ new_data->filespec = malloc(strlen(file->data->filespec) + 1);
+ if (new_data->filespec == NULL) {
+ retval = ENOMEM;
+ } else {
+ strcpy (new_data->filespec, file->data->filespec);
+ }
+ }
+
+ if (retval != 0) {
+ free(new_data);
+ return retval;
+ }
+ profile_dereference_data(file->data);
+ file->data = new_data;
+ }
+#endif /* SHARE_TREE_DATA */
+
retval = profile_update_file(file);
return retval;