Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1689)

Side by Side Diff: third_party/grpc/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #region Copyright notice and license
2
3 // Copyright 2015-2016, Google Inc.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 // * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 #endregion
33
34 using System;
35 using System.Collections.Concurrent;
36 using System.Diagnostics;
37 using System.IO;
38 using System.Reflection;
39 using System.Runtime.InteropServices;
40 using System.Threading;
41
42 using Grpc.Core.Logging;
43 using Grpc.Core.Utils;
44
45 namespace Grpc.Core.Internal
46 {
47 /// <summary>
48 /// Represents a dynamically loaded unmanaged library in a (partially) platf orm independent manner.
49 /// An important difference in library loading semantics is that on Windows, once we load a dynamic library using LoadLibrary,
50 /// that library becomes instantly available for <c>DllImport</c> P/Invoke c alls referring to the same library name.
51 /// On Unix systems, dlopen has somewhat different semantics, so we need to use dlsym and <c>Marshal.GetDelegateForFunctionPointer</c>
52 /// to obtain delegates to native methods.
53 /// See http://stackoverflow.com/questions/13461989/p-invoke-to-dynamically- loaded-library-on-mono.
54 /// </summary>
55 internal class UnmanagedLibrary
56 {
57 static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Unmanage dLibrary>();
58
59 // flags for dlopen
60 const int RTLD_LAZY = 1;
61 const int RTLD_GLOBAL = 8;
62
63 readonly string libraryPath;
64 readonly IntPtr handle;
65
66 public UnmanagedLibrary(string libraryPath)
67 {
68 this.libraryPath = GrpcPreconditions.CheckNotNull(libraryPath);
69
70 if (!File.Exists(this.libraryPath))
71 {
72 throw new FileNotFoundException("Error loading native library. F ile does not exist.", this.libraryPath);
73 }
74
75 Logger.Debug("Attempting to load native library \"{0}\"", this.libra ryPath);
76
77 this.handle = PlatformSpecificLoadLibrary(this.libraryPath);
78
79 if (this.handle == IntPtr.Zero)
80 {
81 throw new IOException(string.Format("Error loading native librar y \"{0}\"", this.libraryPath));
82 }
83 }
84
85 /// <summary>
86 /// Loads symbol in a platform specific way.
87 /// </summary>
88 /// <param name="symbolName"></param>
89 /// <returns></returns>
90 public IntPtr LoadSymbol(string symbolName)
91 {
92 if (PlatformApis.IsLinux)
93 {
94 if (PlatformApis.IsMono)
95 {
96 return Mono.dlsym(this.handle, symbolName);
97 }
98 return Linux.dlsym(this.handle, symbolName);
99 }
100 if (PlatformApis.IsMacOSX)
101 {
102 return MacOSX.dlsym(this.handle, symbolName);
103 }
104 throw new InvalidOperationException("Unsupported platform.");
105 }
106
107 public T GetNativeMethodDelegate<T>(string methodName)
108 where T : class
109 {
110 var ptr = LoadSymbol(methodName);
111 if (ptr == IntPtr.Zero)
112 {
113 throw new MissingMethodException(string.Format("The native metho d \"{0}\" does not exist", methodName));
114 }
115 return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
116 }
117
118 /// <summary>
119 /// Loads library in a platform specific way.
120 /// </summary>
121 private static IntPtr PlatformSpecificLoadLibrary(string libraryPath)
122 {
123 if (PlatformApis.IsWindows)
124 {
125 return Windows.LoadLibrary(libraryPath);
126 }
127 if (PlatformApis.IsLinux)
128 {
129 if (PlatformApis.IsMono)
130 {
131 return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
132 }
133 return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
134 }
135 if (PlatformApis.IsMacOSX)
136 {
137 return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
138 }
139 throw new InvalidOperationException("Unsupported platform.");
140 }
141
142 private static class Windows
143 {
144 [DllImport("kernel32.dll")]
145 internal static extern IntPtr LoadLibrary(string filename);
146 }
147
148 private static class Linux
149 {
150 [DllImport("libdl.so")]
151 internal static extern IntPtr dlopen(string filename, int flags);
152
153 [DllImport("libdl.so")]
154 internal static extern IntPtr dlsym(IntPtr handle, string symbol);
155 }
156
157 private static class MacOSX
158 {
159 [DllImport("libSystem.dylib")]
160 internal static extern IntPtr dlopen(string filename, int flags);
161
162 [DllImport("libSystem.dylib")]
163 internal static extern IntPtr dlsym(IntPtr handle, string symbol);
164 }
165
166 /// <summary>
167 /// On Linux systems, using using dlopen and dlsym results in
168 /// DllNotFoundException("libdl.so not found") if libc6-dev
169 /// is not installed. As a workaround, we load symbols for
170 /// dlopen and dlsym from the current process as on Linux
171 /// Mono sure is linked against these symbols.
172 /// </summary>
173 private static class Mono
174 {
175 [DllImport("__Internal")]
176 internal static extern IntPtr dlopen(string filename, int flags);
177
178 [DllImport("__Internal")]
179 internal static extern IntPtr dlsym(IntPtr handle, string symbol);
180 }
181 }
182 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698