mit-krb5 thread support: initialization and Windows

Ken Raeburn raeburn at MIT.EDU
Mon Apr 5 17:25:55 EDT 2004


On Windows, we can't have statically-initialized mutexes.  On POSIX
systems, we can, if the default mutex attributes are appropriate.  For
Windows, at least, we'll need some run-time code that gets called in a
thread-safe manner to initialize any mutex that might be in use.  I
believe doing the initialization at library load time is the safest on
Windows.

The revised internal API I'm thinking of for the mutex initialization
is:

 // Between these two, we should be able to do pure compile-time
 // and pure run-time initialization.
 //   POSIX:   partial initializer is PTHREAD_MUTEX_INITIALIZER,
 //            finish does nothing
 //   Windows: partial initializer is an invalid handle,
 //            finish does the real initialization work
 //   debug:   partial initializer sets one magic value,
 //            finish verifies and sets a new magic value for
 //              lock/unlock to check
 k5_mutex_t foo_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 int k5_mutex_finish_init(k5_mutex_t *);
 // for dynamic allocation
 int k5_mutex_init(k5_mutex_t *);
 // Must work for both kinds of alloc, even if it means adding flags.
 int k5_mutex_destroy(k5_mutex_t *);

 // As before.
 int k5_mutex_lock(k5_mutex_t *);
 int k5_mutex_unlock(k5_mutex_t *);

In each library, one new function to finish the static mutex init, and
any other library-wide initialization that might be desired.  On
POSIX, this function would be called via the second support function
(see below).  On Windows, it would be called at library load time.
These functions, or functions they calls, should be the only places
that k5_mutex_finish_init gets called.

A second function or macro called at various possible "first" entry
points which either calls pthread_once on the first function (POSIX),
or checks some flag set by the first function (Windows, debug
support), and possibly returns an error.  (In the non-threaded case, a
simple flag can be used to avoid multiple invocations, and the mutexes
don't need initialization anyways.)

A third function for library termination calls mutex_destroy on each
mutex for the library.  This function would be called automatically at
library unload time.  If it turns out to be needed at exit time for
libraries that don't get unloaded, perhaps we should also use
atexit().  Any static mutexes should be cleaned up with
k5_mutex_destroy here.

APIs for these functions not done yet, but we've got initialization
and termination routines already, they can probably be mapped to two
of the above functions.

Comments?

(Coming soon: Per-thread storage internal API.)

Ken


More information about the krbdev mailing list