You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,85 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SubscriptionQueue.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.Util {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
|
||||
// Similar to a Queue<T>, but allows unsubscribing from the underlying queue.
|
||||
//
|
||||
// !! WARNING !!
|
||||
// Mutable struct for performance reasons; optimized for case where Enqueue is never called.
|
||||
// Be careful with usage, e.g. no readonly declarations of this type.
|
||||
//
|
||||
// Type is not thread safe.
|
||||
|
||||
internal struct SubscriptionQueue<T> {
|
||||
|
||||
private LinkedList<T> _list;
|
||||
|
||||
public bool IsEmpty {
|
||||
get { return (_list == null || _list.Count == 0); }
|
||||
}
|
||||
|
||||
public ISubscriptionToken Enqueue(T value) {
|
||||
if (_list == null) {
|
||||
// lazily instantiate the list
|
||||
_list = new LinkedList<T>();
|
||||
}
|
||||
|
||||
LinkedListNode<T> node = _list.AddLast(value);
|
||||
return new SubscriptionToken(node);
|
||||
}
|
||||
|
||||
public void FireAndComplete(Action<T> action) {
|
||||
try {
|
||||
T value;
|
||||
// Use a while loop instead of a foreach since the list might be changing
|
||||
while (TryDequeue(out value)) {
|
||||
action(value);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_list = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryDequeue(out T result) {
|
||||
if (_list != null && _list.First != null) {
|
||||
LinkedListNode<T> theNode = _list.First;
|
||||
_list.RemoveFirst(); // also marks the SubscriptionToken as inactive
|
||||
result = theNode.Value;
|
||||
theNode.Value = default(T); // unroot the value in case it's large
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
result = default(T); // unroot the value in case it's large
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SubscriptionToken : ISubscriptionToken {
|
||||
private readonly LinkedListNode<T> _node;
|
||||
|
||||
public SubscriptionToken(LinkedListNode<T> node) {
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public bool IsActive {
|
||||
get { return (_node.List != null); }
|
||||
}
|
||||
|
||||
public void Unsubscribe() {
|
||||
if (IsActive) {
|
||||
_node.List.Remove(_node);
|
||||
_node.Value = default(T); // unroot the value in case it's large
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user