PageRenderTime 53ms CodeModel.GetById 30ms app.highlight 3ms RepoModel.GetById 17ms app.codeStats 0ms

/Microsoft.Dynamic/ComEventSinksContainer.cs

https://bitbucket.org/stefanrusek/xronos
C# | 90 lines | 54 code | 15 blank | 21 comment | 7 complexity | 51523070eeb2ab4eb6b6615db880abda MD5 | raw file
 1/* ****************************************************************************
 2 *
 3 * Copyright (c) Microsoft Corporation. 
 4 *
 5 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 6 * copy of the license can be found in the License.html file at the root of this distribution. If 
 7 * you cannot locate the  Microsoft Public License, please send an email to 
 8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 9 * by the terms of the Microsoft Public License.
10 *
11 * You must not remove this notice, or any other, from this software.
12 *
13 *
14 * ***************************************************************************/
15using System; using Microsoft;
16
17
18#if !SILVERLIGHT // ComObject
19
20using System.Collections.Generic;
21#if CODEPLEX_40
22using System.Linq.Expressions;
23#else
24using Microsoft.Linq.Expressions;
25#endif
26using System.Runtime.InteropServices;
27
28#if CODEPLEX_40
29namespace System.Dynamic {
30#else
31namespace Microsoft.Scripting {
32#endif
33    /// <summary>
34    /// ComEventSinksContainer is just a regular list with a finalizer.
35    /// This list is usually attached as a custom data for RCW object and 
36    /// is finalized whenever RCW is finalized.
37    /// </summary>
38    internal class ComEventSinksContainer : List<ComEventSink>, IDisposable {
39        private ComEventSinksContainer() {
40        }
41
42        private static readonly object _ComObjectEventSinksKey = new object();
43
44        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
45        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
46        public static ComEventSinksContainer FromRuntimeCallableWrapper(object rcw, bool createIfNotFound) {
47            // !!! Marshal.Get/SetComObjectData has a LinkDemand for UnmanagedCode which will turn into
48            // a full demand. We need to avoid this by making this method SecurityCritical
49            object data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
50            if (data != null || createIfNotFound == false) {
51                return (ComEventSinksContainer)data;
52            }
53
54            lock (_ComObjectEventSinksKey) {
55                data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
56                if (data != null) {
57                    return (ComEventSinksContainer)data;
58                }
59
60                ComEventSinksContainer comEventSinks = new ComEventSinksContainer();
61                if (!Marshal.SetComObjectData(rcw, _ComObjectEventSinksKey, comEventSinks)) {
62                    throw Error.SetComObjectDataFailed();
63                }
64
65                return comEventSinks;
66            }
67        }
68
69        #region IDisposable Members
70
71        public void Dispose() {
72            DisposeAll();
73            GC.SuppressFinalize(this);
74        }
75
76        #endregion
77
78        private void DisposeAll() {
79            foreach (ComEventSink sink in this) {
80                sink.Dispose();
81            }
82        }
83
84        ~ComEventSinksContainer() {
85            DisposeAll();
86        }
87    }
88}
89
90#endif