/*! Notifies all interested listeners of this transaction about the \a event. If \a event is a closing event (ie. TRANSACTION_ENDED, and TRANSACTION_ABORTED), all listeners except those listening to TRANSACTION_WRITTEN will be removed. */ static void notify_transaction_listeners(block_cache* cache, cache_transaction* transaction, int32_t event) { bool isClosing = is_closing_event(event); bool isWritten = is_written_event(event); ListenerList::Iterator iterator = transaction->listeners.GetIterator(); while (iterator.HasNext()) { cache_listener* listener = iterator.Next(); bool remove = (isClosing && !is_written_event(listener->events)) || (isWritten && is_written_event(listener->events)); if (remove) iterator.Remove(); if ((listener->events & event) != 0) add_notification(cache, listener, event, remove); else if (remove) delete_notification(listener); } // This must work asynchronously in the kernel, but since we're not using // most transaction events, we can do it here. flush_pending_notifications(cache); }
/*! Removes and deletes all listeners that are still monitoring this transaction. */ static void remove_transaction_listeners(block_cache* cache, cache_transaction* transaction) { ListenerList::Iterator iterator = transaction->listeners.GetIterator(); while (iterator.HasNext()) { cache_listener* listener = iterator.Next(); iterator.Remove(); delete_notification(listener); } }