Currently it gets locked while a name lookup is in progress, which is not very
efficient. That should be changed, after the code is fixed up so that the
cache works on other platforms.
* include/fake-addrinfo.h: Include k5-thread.h.
(struct fac): Add a mutex.
(plant_face, find_face): Check that mutex is already locked.
(krb5int_lock_fac, krb5int_unlock_fac): Declare.
(fai_add_hosts_by_name): Use them to lock and unlock the mutex.
* util/support/fake-addrinfo.c (krb5int_fac): Initialize the mutex.
(krb5int_init_fac, krb5int_fini_fac): New functions; finish initializing or
destroy the mutex.
(krb5int_lock_fac, krb5int_unlock_fac): New functions; lock the mutex after
calling krb5int_call_thread_support_init, or unlock it.
* util/support/threads.c (krb5int_call_thread_support_init): New function.
(krb5int_init_fac, krb5int_fini_fac): Declare.
(krb5int_thread_support_init, krb5int_thread_support_fini): Call them.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16622
dc483132-0cff-0310-8789-
dd5450dbe970
+2004-07-23 Ken Raeburn <raeburn@mit.edu>
+
+ * fake-addrinfo.h: Include k5-thread.h.
+ (struct fac): Add a mutex.
+ (plant_face, find_face): Check that mutex is already locked.
+ (krb5int_lock_fac, krb5int_unlock_fac): Declare.
+ (fai_add_hosts_by_name): Use them to lock and unlock the mutex.
+
2004-07-22 Ken Raeburn <raeburn@mit.edu>
* configure.in: Look for "struct lifconf" and maybe define
#include "port-sockets.h"
#include "socket-utils.h"
#include "k5-platform.h"
+#include "k5-thread.h"
#include <stdio.h> /* for sprintf */
/* fake addrinfo cache */
struct fac {
+ k5_mutex_t lock;
struct face *data;
};
extern struct fac krb5int_fac;
if (entry->name == NULL)
/* @@ Wastes memory. */
return;
+ k5_mutex_assert_locked(&krb5int_fac.lock);
entry->next = krb5int_fac.data;
entry->expiration = time(0) + CACHE_ENTRY_LIFETIME;
krb5int_fac.data = entry;
#ifdef DEBUG_ADDRINFO
printf("scanning cache at %d for '%s'...\n", now, name);
#endif
+ k5_mutex_assert_locked(&krb5int_fac.lock);
for (fpp = &krb5int_fac.data; *fpp; ) {
fp = *fpp;
#ifdef DEBUG_ADDRINFO
#endif
+extern int krb5int_lock_fac(void), krb5int_unlock_fac(void);
+
static inline int fai_add_hosts_by_name (const char *name,
struct addrinfo *template,
int portnum, int flags,
#ifdef FAI_CACHE
struct face *ce;
- int i, r;
+ int i, r, err;
+ err = krb5int_lock_fac();
+ if (err) {
+ errno = err;
+ return EAI_SYSTEM;
+ }
if (!find_face(name, &ce)) {
struct addrinfo myhints = { 0 }, *ai, *ai2;
int i4, i6, aierr;
asked for IPv4 only, but let's deal with that later, if we
have to. */
aierr = system_getaddrinfo(name, "telnet", &myhints, &ai);
- if (aierr)
+ if (aierr) {
+ krb5int_unlock_fac();
return aierr;
+ }
ce = malloc(sizeof(struct face));
memset(ce, 0, sizeof(*ce));
ce->expiration = time(0) + 30;
}
ce->addrs4 = calloc(ce->naddrs4, sizeof(*ce->addrs4));
if (ce->addrs4 == NULL && ce->naddrs4 != 0) {
+ krb5int_unlock_fac();
system_freeaddrinfo(ai);
return EAI_MEMORY;
}
ce->addrs6 = calloc(ce->naddrs6, sizeof(*ce->addrs6));
if (ce->addrs6 == NULL && ce->naddrs6 != 0) {
+ krb5int_unlock_fac();
free(ce->addrs4);
system_freeaddrinfo(ai);
return EAI_MEMORY;
template->ai_addrlen = sizeof(struct sockaddr_in6);
for (i = 0; i < ce->naddrs6; i++) {
r = fai_add_entry (result, &ce->addrs6[i], portnum, template);
- if (r)
+ if (r) {
+ krb5int_unlock_fac();
return r;
+ }
}
template->ai_family = AF_INET;
template->ai_addrlen = sizeof(struct sockaddr_in);
for (i = 0; i < ce->naddrs4; i++) {
r = fai_add_entry (result, &ce->addrs4[i], portnum, template);
- if (r)
+ if (r) {
+ krb5int_unlock_fac();
return r;
+ }
}
if (*result && (flags & AI_CANONNAME))
(*result)->ai_canonname = strdup(ce->canonname);
+ krb5int_unlock_fac();
return 0;
#else
+2004-07-23 Ken Raeburn <raeburn@mit.edu>
+
+ * fake-addrinfo.c (krb5int_fac): Initialize the mutex.
+ (krb5int_init_fac, krb5int_fini_fac): New functions; finish
+ initializing or destroy the mutex.
+ (krb5int_lock_fac, krb5int_unlock_fac): New functions; lock the
+ mutex after calling krb5int_call_thread_support_init, or unlock
+ it.
+ * threads.c (krb5int_call_thread_support_init): New function.
+ (krb5int_init_fac, krb5int_fini_fac): Declare.
+ (krb5int_thread_support_init, krb5int_thread_support_fini): Call
+ them.
+
2004-07-19 Ken Raeburn <raeburn@mit.edu>
* fake-addrinfo.c: New file.
#include "fake-addrinfo.h"
/* Allocate the storage here. */
-struct fac krb5int_fac = { 0 };
+struct fac krb5int_fac = { K5_MUTEX_PARTIAL_INITIALIZER, 0 };
+
+int krb5int_init_fac (void)
+{
+ return k5_mutex_finish_init(&krb5int_fac.lock);
+}
+
+void krb5int_fini_fac (void)
+{
+ k5_mutex_destroy(&krb5int_fac.lock);
+}
+
+extern int krb5int_call_thread_support_init(void);
+int krb5int_lock_fac (void)
+{
+ int err;
+ err = krb5int_call_thread_support_init();
+ if (err)
+ return err;
+ return k5_mutex_lock(&krb5int_fac.lock);
+}
+
+int krb5int_unlock_fac (void)
+{
+ return k5_mutex_unlock(&krb5int_fac.lock);
+}
return 0;
}
+int krb5int_call_thread_support_init (void)
+{
+ return CALL_INIT_FUNCTION(krb5int_thread_support_init);
+}
+
+extern int krb5int_init_fac(void);
+extern void krb5int_fini_fac(void);
+
int krb5int_thread_support_init (void)
{
+ int err;
+
#ifndef ENABLE_THREADS
- return 0;
+ /* Nothing to do for TLS initialization. */
#elif defined(_WIN32)
tls_idx = TlsAlloc();
/* XXX This can raise an exception if memory is low! */
InitializeCriticalSection(&key_lock);
- return 0;
#else /* POSIX */
- int err;
err = k5_mutex_finish_init(&key_lock);
if (err)
return err;
if (K5_PTHREADS_LOADED)
return pthread_key_create(&key, thread_termination);
- else
- return 0;
#endif
+
+ err = krb5int_init_fac();
+ if (err)
+ return err;
+
+ return 0;
}
void krb5int_thread_support_fini (void)
{
+ if (! INITIALIZER_RAN (krb5int_thread_support_init))
+ return;
+
#ifndef ENABLE_THREADS
/* Do nothing. */
#elif defined(_WIN32)
- if (! INITIALIZER_RAN (krb5int_thread_support_init))
- return;
/* ... free stuff ... */
TlsFree(tls_idx);
DeleteCriticalSection(&key_lock);
k5_mutex_destroy(&key_lock);
#endif
+
+ krb5int_fini_fac();
}