From bf5c81d77e492cd6df5517ecab32cd64168b01c2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 May 2010 15:59:48 -0700 Subject: * Initial commit of the slimupdates2 rewrite. This pass maintains the original behavior of avatar update sending and has a simplified set of IClientAPI methods for sending avatar/prim updates --- OpenSim/Framework/Lazy.cs | 236 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 OpenSim/Framework/Lazy.cs (limited to 'OpenSim/Framework/Lazy.cs') diff --git a/OpenSim/Framework/Lazy.cs b/OpenSim/Framework/Lazy.cs new file mode 100644 index 0000000..8a417ac --- /dev/null +++ b/OpenSim/Framework/Lazy.cs @@ -0,0 +1,236 @@ +// +// Lazy.cs +// +// Authors: +// Zoltan Varga (vargaz@gmail.com) +// Marek Safar (marek.safar@gmail.com) +// +// Copyright (C) 2009 Novell +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Runtime.Serialization; +using System.Runtime.InteropServices; +using System.Security.Permissions; +using System.Threading; +using System.Diagnostics; + +namespace OpenSim.Framework +{ + public enum LazyThreadSafetyMode + { + None, + PublicationOnly, + ExecutionAndPublication + } + + [SerializableAttribute] + [ComVisibleAttribute(false)] + [HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] + public class Lazy + { + T value; + bool inited; + LazyThreadSafetyMode mode; + Func factory; + object monitor; + Exception exception; + + public Lazy() + : this(LazyThreadSafetyMode.ExecutionAndPublication) + { + } + + public Lazy(Func valueFactory) + : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication) + { + } + + public Lazy(bool isThreadSafe) + : this(() => Activator.CreateInstance(), isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None) + { + } + + public Lazy(Func valueFactory, bool isThreadSafe) + : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None) + { + } + + public Lazy(LazyThreadSafetyMode mode) + : this(() => Activator.CreateInstance(), mode) + { + } + + public Lazy(Func valueFactory, LazyThreadSafetyMode mode) + { + if (valueFactory == null) + throw new ArgumentNullException("valueFactory"); + this.factory = valueFactory; + if (mode != LazyThreadSafetyMode.None) + monitor = new object(); + this.mode = mode; + } + + // Don't trigger expensive initialization + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public T Value + { + get + { + if (inited) + return value; + if (exception != null) + throw exception; + + return InitValue(); + } + } + + T InitValue() + { + switch (mode) + { + case LazyThreadSafetyMode.None: + { + var init_factory = factory; + if (init_factory == null) + throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance"); + try + { + factory = null; + T v = init_factory(); + value = v; + Thread.MemoryBarrier(); + inited = true; + } + catch (Exception ex) + { + exception = ex; + throw; + } + break; + } + case LazyThreadSafetyMode.PublicationOnly: + { + var init_factory = factory; + T v; + + //exceptions are ignored + if (init_factory != null) + v = init_factory(); + else + v = default(T); + + lock (monitor) + { + if (inited) + return value; + value = v; + Thread.MemoryBarrier(); + inited = true; + factory = null; + } + break; + } + case LazyThreadSafetyMode.ExecutionAndPublication: + { + lock (monitor) + { + if (inited) + return value; + + if (factory == null) + throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance"); + + var init_factory = factory; + try + { + factory = null; + T v = init_factory(); + value = v; + Thread.MemoryBarrier(); + inited = true; + } + catch (Exception ex) + { + exception = ex; + throw; + } + } + break; + } + default: + throw new InvalidOperationException("Invalid LazyThreadSafetyMode " + mode); + } + + if (monitor == null) + { + value = factory(); + inited = true; + } + else + { + lock (monitor) + { + if (inited) + return value; + + if (factory == null) + throw new InvalidOperationException("The initialization function tries to access Value on this instance"); + + var init_factory = factory; + try + { + factory = null; + T v = init_factory(); + value = v; + Thread.MemoryBarrier(); + inited = true; + } + catch + { + factory = init_factory; + throw; + } + } + } + + return value; + } + + public bool IsValueCreated + { + get + { + return inited; + } + } + + public override string ToString() + { + if (inited) + return value.ToString(); + else + return "Value is not created"; + } + } +} -- cgit v1.1