Add support on Windows to install atexit handler(s) early in application’s startup.
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsObject.cs
1 //
2 // MonoBtlsObject.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 #if SECURITY_DEP
27 using System;
28 using System.Threading;
29 using System.Runtime.InteropServices;
30 using System.Runtime.CompilerServices;
31
32 namespace Mono.Btls
33 {
34         abstract class MonoBtlsObject : IDisposable
35         {
36                 internal MonoBtlsObject (MonoBtlsHandle handle)
37                 {
38                         this.handle = handle;
39                 }
40
41                 protected internal abstract class MonoBtlsHandle : SafeHandle
42                 {
43                         internal MonoBtlsHandle ()
44                                 : base (IntPtr.Zero, true)
45                         {
46                         }
47
48                         internal MonoBtlsHandle (IntPtr handle, bool ownsHandle)
49                                 : base (handle, ownsHandle)
50                         {
51                         }
52
53                         public override bool IsInvalid {
54                                 get { return handle == IntPtr.Zero; }
55                         }
56                 }
57
58                 internal MonoBtlsHandle Handle {
59                         get {
60                                 CheckThrow ();
61                                 return handle;
62                         }
63                 }
64
65                 public bool IsValid {
66                         get { return handle != null && !handle.IsInvalid; }
67                 }
68
69                 MonoBtlsHandle handle;
70                 Exception lastError;
71
72                 protected void CheckThrow ()
73                 {
74                         if (lastError != null)
75                                 throw lastError;
76                         if (handle == null || handle.IsInvalid)
77                                 throw new ObjectDisposedException ("MonoBtlsSsl");
78                 }
79
80                 protected Exception SetException (Exception ex)
81                 {
82                         if (lastError == null)
83                                 lastError = ex;
84                         return ex;
85                 }
86
87                 protected void CheckError (bool ok, [CallerMemberName] string callerName = null)
88                 {
89                         if (!ok) {
90                                 if (callerName != null)
91                                         throw new MonoBtlsException ("{0}.{1} failed.", GetType ().Name, callerName);
92                                 else
93                                         throw new MonoBtlsException ();
94                         }
95
96                 }
97
98                 protected void CheckError (int ret, [CallerMemberName] string callerName = null)
99                 {
100                         CheckError (ret == 1, callerName);
101                 }
102
103                 [MethodImpl (MethodImplOptions.InternalCall)]
104                 extern static void mono_btls_free (IntPtr data);
105
106                 protected void FreeDataPtr (IntPtr data)
107                 {
108                         mono_btls_free (data);
109                 }
110
111                 protected virtual void Close ()
112                 {
113                 }
114
115                 protected void Dispose (bool disposing)
116                 {
117                         if (disposing) {
118                                 try {
119                                         if (handle != null) {
120                                                 Close ();
121                                                 handle.Dispose ();
122                                                 handle = null;
123                                         }
124                                 } finally {
125                                         var disposedExc = new ObjectDisposedException (GetType ().Name);
126                                         Interlocked.CompareExchange (ref lastError, disposedExc, null);
127                                 }
128                         }
129                 }
130
131                 public void Dispose ()
132                 {
133                         Dispose (true);
134                         GC.SuppressFinalize (this);
135                 }
136
137                 ~MonoBtlsObject ()
138                 {
139                         Dispose (false);
140                 }
141         }
142 }
143 #endif