/Microsoft.Dynamic/ComEventSinksContainer.cs
C# | 90 lines | 54 code | 15 blank | 21 comment | 7 complexity | 51523070eeb2ab4eb6b6615db880abda MD5 | raw file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Microsoft Public License. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Microsoft Public License, please send an email to
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Microsoft Public License.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
- using System; using Microsoft;
-
-
- #if !SILVERLIGHT // ComObject
-
- using System.Collections.Generic;
- #if CODEPLEX_40
- using System.Linq.Expressions;
- #else
- using Microsoft.Linq.Expressions;
- #endif
- using System.Runtime.InteropServices;
-
- #if CODEPLEX_40
- namespace System.Dynamic {
- #else
- namespace Microsoft.Scripting {
- #endif
- /// <summary>
- /// ComEventSinksContainer is just a regular list with a finalizer.
- /// This list is usually attached as a custom data for RCW object and
- /// is finalized whenever RCW is finalized.
- /// </summary>
- internal class ComEventSinksContainer : List<ComEventSink>, IDisposable {
- private ComEventSinksContainer() {
- }
-
- private static readonly object _ComObjectEventSinksKey = new object();
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
- public static ComEventSinksContainer FromRuntimeCallableWrapper(object rcw, bool createIfNotFound) {
- // !!! Marshal.Get/SetComObjectData has a LinkDemand for UnmanagedCode which will turn into
- // a full demand. We need to avoid this by making this method SecurityCritical
- object data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
- if (data != null || createIfNotFound == false) {
- return (ComEventSinksContainer)data;
- }
-
- lock (_ComObjectEventSinksKey) {
- data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
- if (data != null) {
- return (ComEventSinksContainer)data;
- }
-
- ComEventSinksContainer comEventSinks = new ComEventSinksContainer();
- if (!Marshal.SetComObjectData(rcw, _ComObjectEventSinksKey, comEventSinks)) {
- throw Error.SetComObjectDataFailed();
- }
-
- return comEventSinks;
- }
- }
-
- #region IDisposable Members
-
- public void Dispose() {
- DisposeAll();
- GC.SuppressFinalize(this);
- }
-
- #endregion
-
- private void DisposeAll() {
- foreach (ComEventSink sink in this) {
- sink.Dispose();
- }
- }
-
- ~ComEventSinksContainer() {
- DisposeAll();
- }
- }
- }
-
- #endif