FreeBSD/sys/kern/kern_lockf.c
/*
 * Add a lock to the active list, updating or removing any current
 * locks owned by the same owner and processing any pending locks that
 * become unblocked as a result. This code is also used for unlock
 * since the logic for updating existing locks is identical.
 *
 * As a result of processing the new lock, we may unblock existing
 * pending locks as a result of downgrading/unlocking. We simply
 * activate the newly granted locks by looping.
 *
 * Since the new lock already has its dependencies set up, we always
 * add it to the list (unless its an unlock request). This may
 * fragment the lock list in some pathological cases but its probably
 * not a real problem.
 */
Add a lock to the active list, updating or removing any current
locks owned by the same owner and processing any pending locks that
become unblocked as a result. This code is also used for unlock
since the logic for updating existing locks is identical.

As a result of processing the new lock, we may unblock existing
pending locks as a result of downgrading/unlocking. We simply
activate the newly granted locks by looping.

Since the new lock already has its dependencies set up, we always
add it to the list (unless its an unlock request). This may
fragment the lock list in some pathological cases but its probably
not a real problem.
Add a lock to the active list updating or removing any current locks owned by the same owner and processing any pending locks that become unblocked as a result . This code is also used for unlock since the logic for updating existing locks is identical . As a result of processing the new lock we may unblock existing pending locks as a result of downgrading / unlocking . We simply activate the newly granted locks by looping . Since the new lock already has its dependencies set up we always add it to the list ( unless its an unlock request ) . This may fragment the lock list in some pathological cases but its probably not a real problem .
static void
lf_activate_lock(struct lockf *state, struct lockf_entry *lock)
{
	struct lockf_entry *overlap, *lf;
	struct lockf_entry_list granted;
	int ovcase;
	LIST_INIT(&granted);
	LIST_INSERT_HEAD(&granted, lock, lf_link);
	while (!LIST_EMPTY(&granted)) {
		lock = LIST_FIRST(&granted);
		LIST_REMOVE(lock, lf_link);
		overlap = LIST_FIRST(&state->ls_active);
		for (;;) {
			ovcase = lf_findoverlap(&overlap, lock, SELF);
#ifdef LOCKF_DEBUG
			if (ovcase && (lockf_debug & 2)) {
				printf("lf_setlock: overlap %d", ovcase);
				lf_print("", overlap);
			}
#endif
			switch (ovcase) {
			case 0: 
				break;
			case 1: 
				LIST_REMOVE(overlap, lf_link);
				lf_update_dependancies(state, overlap, TRUE,
					&granted);
				lf_free_lock(overlap);
				break;
			case 2: 
				lf_split(state, overlap, lock, &granted);
				break;
			case 3: 
				lf = LIST_NEXT(overlap, lf_link);
				LIST_REMOVE(overlap, lf_link);
				lf_update_dependancies(state, overlap, TRUE,
					&granted);
				lf_free_lock(overlap);
				overlap = lf;
				continue;
			case 4: 
				lf_set_end(state, overlap, lock->lf_start - 1,
				    &granted);
				overlap = LIST_NEXT(overlap, lf_link);
				continue;
			case 5: 
				lf_set_start(state, overlap, lock->lf_end + 1,
				    &granted);
				break;
			}
			break;
		}
#ifdef LOCKF_DEBUG
		if (lockf_debug & 1) {
			if (lock->lf_type != F_UNLCK)
				lf_print("lf_activate_lock: activated", lock);
			else
				lf_print("lf_activate_lock: unlocked", lock);
			lf_printlist("lf_activate_lock", lock);
		}
#endif 
		if (lock->lf_type != F_UNLCK)
			lf_insert_lock(state, lock);
	}
}
static void lf_activate_lock ( struct lockf * state , struct lockf_entry * lock ) { struct lockf_entry * overlap , * lf ; struct lockf_entry_list granted ; int ovcase ; LIST_INIT ( & granted ) ; LIST_INSERT_HEAD ( & granted , lock , lf_link ) ; while ( ! LIST_EMPTY ( & granted ) ) { lock = LIST_FIRST ( & granted ) ; LIST_REMOVE ( lock , lf_link ) ; overlap = LIST_FIRST ( & state -> ls_active ) ; for ( ; ; ) { ovcase = lf_findoverlap ( & overlap , lock , SELF ) ; #ifdef LOCKF_DEBUG if ( ovcase && ( lockf_debug & 2 ) ) { printf ( " " , ovcase ) ; lf_print ( " " , overlap ) ; } #endif switch ( ovcase ) { case 0 : break ; case 1 : LIST_REMOVE ( overlap , lf_link ) ; lf_update_dependancies ( state , overlap , TRUE , & granted ) ; lf_free_lock ( overlap ) ; break ; case 2 : lf_split ( state , overlap , lock , & granted ) ; break ; case 3 : lf = LIST_NEXT ( overlap , lf_link ) ; LIST_REMOVE ( overlap , lf_link ) ; lf_update_dependancies ( state , overlap , TRUE , & granted ) ; lf_free_lock ( overlap ) ; overlap = lf ; continue ; case 4 : lf_set_end ( state , overlap , lock -> lf_start - 1 , & granted ) ; overlap = LIST_NEXT ( overlap , lf_link ) ; continue ; case 5 : lf_set_start ( state , overlap , lock -> lf_end + 1 , & granted ) ; break ; } break ; } #ifdef LOCKF_DEBUG if ( lockf_debug & 1 ) { if ( lock -> lf_type != F_UNLCK ) lf_print ( " " , lock ) ; else lf_print ( " " , lock ) ; lf_printlist ( " " , lock ) ; } #endif if ( lock -> lf_type != F_UNLCK ) lf_insert_lock ( state , lock ) ; } }
Add a lock to the active list, updating or removing any current
 locks owned by the same owner and processing any pending locks that
 become unblocked as a result.
Add a lock to the active list updating or removing any current locks owned by the same owner and processing any pending locks that become unblocked as a result .
/*
		 * Skip over locks owned by other processes.  Handle
		 * any locks that overlap and are owned by ourselves.
		 */ /*
			 * Six cases:
			 *	0) no overlap
			 *	1) overlap == lock
			 *	2) overlap contains lock
			 *	3) lock contains overlap
			 *	4) overlap starts before lock
			 *	5) overlap ends after lock
			 */ /* no overlap */ /* overlap == lock */ /*
				 * We have already setup the
				 * dependants for the new lock, taking
				 * into account a possible downgrade
				 * or unlock. Remove the old lock.
				 */ /* overlap contains lock */ /*
				 * Just split the existing lock.
				 */ /* lock contains overlap */ /*
				 * Delete the overlap and advance to
				 * the next entry in the list.
				 */ /* overlap starts before lock */ /*
				 * Just update the overlap end and
				 * move on.
				 */ /* overlap ends after lock */ /*
				 * Change the start of overlap and
				 * re-insert.
				 */ /* LOCKF_DEBUG */