PageRenderTime 55ms CodeModel.GetById 30ms RepoModel.GetById 1ms 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. * ***************************************************************************/
  15. using System; using Microsoft;
  16. #if !SILVERLIGHT // ComObject
  17. using System.Collections.Generic;
  18. #if CODEPLEX_40
  19. using System.Linq.Expressions;
  20. #else
  21. using Microsoft.Linq.Expressions;
  22. #endif
  23. using System.Runtime.InteropServices;
  24. #if CODEPLEX_40
  25. namespace System.Dynamic {
  26. #else
  27. namespace Microsoft.Scripting {
  28. #endif
  29. /// <summary>
  30. /// ComEventSinksContainer is just a regular list with a finalizer.
  31. /// This list is usually attached as a custom data for RCW object and
  32. /// is finalized whenever RCW is finalized.
  33. /// </summary>
  34. internal class ComEventSinksContainer : List<ComEventSink>, IDisposable {
  35. private ComEventSinksContainer() {
  36. }
  37. private static readonly object _ComObjectEventSinksKey = new object();
  38. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
  39. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
  40. public static ComEventSinksContainer FromRuntimeCallableWrapper(object rcw, bool createIfNotFound) {
  41. // !!! Marshal.Get/SetComObjectData has a LinkDemand for UnmanagedCode which will turn into
  42. // a full demand. We need to avoid this by making this method SecurityCritical
  43. object data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
  44. if (data != null || createIfNotFound == false) {
  45. return (ComEventSinksContainer)data;
  46. }
  47. lock (_ComObjectEventSinksKey) {
  48. data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
  49. if (data != null) {
  50. return (ComEventSinksContainer)data;
  51. }
  52. ComEventSinksContainer comEventSinks = new ComEventSinksContainer();
  53. if (!Marshal.SetComObjectData(rcw, _ComObjectEventSinksKey, comEventSinks)) {
  54. throw Error.SetComObjectDataFailed();
  55. }
  56. return comEventSinks;
  57. }
  58. }
  59. #region IDisposable Members
  60. public void Dispose() {
  61. DisposeAll();
  62. GC.SuppressFinalize(this);
  63. }
  64. #endregion
  65. private void DisposeAll() {
  66. foreach (ComEventSink sink in this) {
  67. sink.Dispose();
  68. }
  69. }
  70. ~ComEventSinksContainer() {
  71. DisposeAll();
  72. }
  73. }
  74. }
  75. #endif