FreeBSD/sys/netpfil/ipfw/ip_fw_sockopt.c
/*
 * Adds one or more sockopt handlers to the global array.
 * Function may sleep.
 */
Adds one or more sockopt handlers to the global array.
Function may sleep.
Adds one or more sockopt handlers to the global array . Function may sleep .
void
ipfw_add_sopt_handler(struct ipfw_sopt_handler *sh, size_t count)
{
	size_t sz;
	struct ipfw_sopt_handler *tmp;
	CTL3_LOCK();
	for (;;) {
		sz = ctl3_hsize + count;
		CTL3_UNLOCK();
		tmp = malloc(sizeof(*sh) * sz, M_IPFW, M_WAITOK | M_ZERO);
		CTL3_LOCK();
		if (ctl3_hsize + count <= sz)
			break;
		free(tmp, M_IPFW);
	}
	sz = ctl3_hsize + count;
	memcpy(tmp, ctl3_handlers, ctl3_hsize * sizeof(*sh));
	memcpy(&tmp[ctl3_hsize], sh, count * sizeof(*sh));
	qsort(tmp, sz, sizeof(*sh), compare_sh);
	if (ctl3_handlers != NULL)
		free(ctl3_handlers, M_IPFW);
	ctl3_handlers = tmp;
	ctl3_hsize = sz;
	ctl3_gencnt++;
	CTL3_UNLOCK();
}
void ipfw_add_sopt_handler ( struct ipfw_sopt_handler * sh , size_t count ) { size_t sz ; struct ipfw_sopt_handler * tmp ; CTL3_LOCK ( ) ; for ( ; ; ) { sz = ctl3_hsize + count ; CTL3_UNLOCK ( ) ; tmp = malloc ( sizeof ( * sh ) * sz , M_IPFW , M_WAITOK | M_ZERO ) ; CTL3_LOCK ( ) ; if ( ctl3_hsize + count <= sz ) break ; free ( tmp , M_IPFW ) ; } sz = ctl3_hsize + count ; memcpy ( tmp , ctl3_handlers , ctl3_hsize * sizeof ( * sh ) ) ; memcpy ( & tmp [ ctl3_hsize ] , sh , count * sizeof ( * sh ) ) ; qsort ( tmp , sz , sizeof ( * sh ) , compare_sh ) ; if ( ctl3_handlers != NULL ) free ( ctl3_handlers , M_IPFW ) ; ctl3_handlers = tmp ; ctl3_hsize = sz ; ctl3_gencnt ++ ; CTL3_UNLOCK ( ) ; }
Adds one or more sockopt handlers to the global array.
Adds one or more sockopt handlers to the global array .
/* Retry */ /* Merge old & new arrays */ /* Switch new and free old */