compiling 1.4 for freebsd 5.3 errors

Dan Drake ddrake at
Thu Feb 10 18:47:34 EST 2005

I think I have found something that I can't understand how it ever could 
possible work.  I may be missing something (from tracing macros all day, 
so feel free to correct me.

First, the assert below is going off.

#  define k5_call_init_function(I)                  \
    (__extension__ ({                       \
        k5_init_t *k5int_i = (I);               \
        int k5int_err = k5_once(&k5int_i->once, k5int_i->fn);   \
        (k5int_err                      \
         ? k5int_err                        \
         : (assert(k5int_i->did_run != 0), k5int_i->error));    \

Now I am looking at k5_once, and find :

# define k5_once(O,F)   (K5_PTHREADS_LOADED         \
             ? pthread_once(&(O)->o,F)      \
             : k5_os_nothread_once(&(O)->n,F))

now PTHREADS have a value of 1 so pthread_once is called

if we look at the source for pthread_once in the bsd tree we find:

_pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
	struct pthread *curthread;
	int wakeup = 0;

	if (once_control->state == ONCE_DONE)
		return (0);
	while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS)
		_pthread_cond_wait(&once_cv, &once_lock);
	 * If previous thread was canceled, then the state still
	 * could be ONCE_NEVER_DONE, we need to check it again.
	if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) {
		once_control->state = ONCE_IN_PROGRESS;
		curthread = _get_curthread();
		THR_CLEANUP_PUSH(curthread, once_cancel_handler, once_control);
		THR_CLEANUP_POP(curthread, 0);
		once_control->state = ONCE_DONE;
		wakeup = 1;

It didn't set did_run.  In fact it can't set did run because it doesn't have access to the state at that level.
so we assert.  Is the proper fix not to assert of did_run?  or if k5_once returns 0 to set did_run?

Any thoughts?


More information about the krbdev mailing list