/*! 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; }