/*!	Calls low resource handlers for the given resources.
	sLowResourceLock must be held.
*/
static void
call_handlers(uint32 lowResources)
{
	if (sLowResourceHandlers.IsEmpty())
		return;

	// Add a marker, so we can drop the lock while calling the handlers and
	// still iterate safely.
	low_resource_handler marker;
	sLowResourceHandlers.Insert(&marker, false);

	while (low_resource_handler* handler
			= sLowResourceHandlers.GetNext(&marker)) {
		// swap with handler
		sLowResourceHandlers.Swap(&marker, handler);
		marker.priority = handler->priority;

		int32 resources = handler->resources & lowResources;
		if (resources != 0) {
			recursive_lock_unlock(&sLowResourceLock);
			handler->function(handler->data, resources,
				low_resource_state_no_update(resources));
			recursive_lock_lock(&sLowResourceLock);
		}
	}

	// remove marker
	sLowResourceHandlers.Remove(&marker);
}
/*! Registers a low resource handler. The higher the \a priority, the earlier
	the handler will be called in low resource situations.
*/
status_t
register_low_resource_handler(low_resource_func function, void* data,
	uint32 resources, int32 priority)
{
	TRACE(("register_low_resource_handler(function = %p, data = %p)\n",
		function, data));

	low_resource_handler *newHandler = (low_resource_handler*)malloc(
		sizeof(low_resource_handler));
	if (newHandler == NULL)
		return B_NO_MEMORY;

	newHandler->function = function;
	newHandler->data = data;
	newHandler->resources = resources;
	newHandler->priority = priority;

	RecursiveLocker locker(&sLowResourceLock);

	// sort it in after priority (higher priority comes first)

	HandlerList::ReverseIterator iterator
		= sLowResourceHandlers.GetReverseIterator();
	low_resource_handler* last = NULL;
	while (iterator.HasNext()) {
		low_resource_handler *handler = iterator.Next();

		if (handler->priority >= priority) {
			sLowResourceHandlers.Insert(last, newHandler);
			return B_OK;
		}
		last = handler;
	}

	sLowResourceHandlers.Add(newHandler, false);
	return B_OK;
}