-
Notifications
You must be signed in to change notification settings - Fork 21
/
Event.cs
315 lines (242 loc) · 15.9 KB
/
Event.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
using System;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Runtime.InteropServices;
namespace EvHttpSharp.Interop
{
static class Event
{
// ReSharper disable InconsistentNaming
[StructLayout(LayoutKind.Sequential)]
internal struct sockaddr_in
{
internal short sin_family;
internal ushort sin_port;
internal int sin_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
internal byte[] sin_zero;
}
public const int AF_INET = 2;
public static class D
{
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_base_free(IntPtr eventBase);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EventBase event_base_new();
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvHttp evhttp_new(EventBase eventBase);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_free(IntPtr evhttp);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void thread_model_selector();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void log_cb(int sev, IntPtr message);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_set_log_callback(log_cb cb);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_request_callback(IntPtr request, IntPtr arg);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_set_gencb(EvHttp http, evhttp_request_callback cb, IntPtr arg);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvHttpBoundSocket evhttp_bind_socket_with_handle(
EvHttp http, [MarshalAs(UnmanagedType.LPStr)] string host, ushort port);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_del_accept_socket(EvHttp evhttp, EvHttpBoundSocket socket);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_base_dispatch(EventBase eventBase);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_base_loopbreak(EventBase eventBase);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_send_reply(
EvHttpRequest req, int code, [MarshalAs(UnmanagedType.LPStr)] string desc, EvBuffer buffer);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_set_allowed_methods(EvHttp http, EvHttpCmdType methods);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvHttpCmdType evhttp_request_get_command(EvHttpRequest request);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvHttpConnection evhttp_request_get_connection (EvHttpRequest request);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate IntPtr evhttp_request_get_uri(EvHttpRequest request);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate IntPtr evhttp_request_get_host(EvHttpRequest request);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate IntPtr evhttp_request_get_input_headers(EvHttpRequest request);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr evhttp_request_get_input_buffer(EvHttpRequest request);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void evhttp_connection_get_peer(EvHttpConnection connection, ref IntPtr pHostString, ref ushort port);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvBuffer evbuffer_new();
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evbuffer_free (IntPtr handle);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate IntPtr evbuffer_get_length(EvBuffer buffer);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate int evbuffer_remove(EvBuffer evBuffer, byte[] buffer, IntPtr len);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate int evbuffer_add (EvBuffer evBuffer, byte[] buffer, IntPtr len);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate IntPtr evhttp_request_get_output_headers (EvHttpRequest request);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void evhttp_add_header(
IntPtr headers, [MarshalAs(UnmanagedType.LPStr)] string header, [MarshalAs(UnmanagedType.LPStr)] string value);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate int event_base_loop(EventBase eventBase, EvLoopFlags flags);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate int event_free (IntPtr ev);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_active (IntPtr ev, int res = 0, short ignored = 0);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void evconnlistener_free(IntPtr handle);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvHttpBoundSocket evhttp_bind_listener(EvHttp http, EvConnListener listener);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvConnListener evconnlistener_new_bind(
EventBase evBase, IntPtr cb, IntPtr ptr, uint flags, int backlog, ref sockaddr_in sockaddr, int socklen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int evhttp_add_virtual_host(
EvHttp http, [MarshalAs(UnmanagedType.LPStr)] string pattern, out IntPtr host);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int evhttp_add_server_alias(
EvHttp http, [MarshalAs(UnmanagedType.LPStr)] string pattern);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int evhttp_remove_server_alias(
EvHttp http, [MarshalAs(UnmanagedType.LPStr)] string pattern);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int evhttp_remove_virtual_host(
EvHttp http, EvHttp host);
#region *nix
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_callback_normal(int fd, short events, IntPtr arg);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvEvent event_new_normal (EventBase eventBase, int fd, short events, event_callback_normal cb, IntPtr arg);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int evconnlistener_get_fd_normal(EvConnListener l);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvHttpBoundSocket evhttp_accept_socket_with_handle_normal(EvHttp http, int fd);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvConnListener evconnlistener_new_normal(
EventBase evBase, IntPtr cb, IntPtr ptr, uint flags, int backlog, int fd);
#endregion
#region Windows
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate void event_callback_windows(IntPtr fd, short events, IntPtr arg);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
public delegate EvEvent event_new_windows(EventBase eventBase, IntPtr fd, short events, event_callback_windows cb, IntPtr arg);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr evconnlistener_get_fd_windows(EvConnListener l);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvHttpBoundSocket evhttp_accept_socket_with_handle_windows(EvHttp http, IntPtr fd);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate EvConnListener evconnlistener_new_windows(
EventBase evBase, IntPtr cb, IntPtr ptr, uint flags, int backlog, IntPtr fd);
#endregion
}
// ReSharper restore InconsistentNaming
[EvImport] public static D.event_set_log_callback EventSetLogCallback;
[EvImport] public static D.event_base_free EventBaseFree;
[EvImport] public static D.event_base_new EventBaseNew;
[EvImport] public static D.event_base_dispatch EventBaseDispatch;
[EvImport] public static D.event_base_loopbreak EventBaseLoopbreak;
[EvImport] public static D.evbuffer_free EvBufferFree;
[EvImport] public static D.evbuffer_new EvBufferNew;
[EvImport] public static D.evbuffer_get_length EvBufferGetLength;
[EvImport] public static D.evbuffer_remove EvBufferRemove;
[EvImport] public static D.evbuffer_add EvBufferAdd;
[EvImport] public static D.event_base_loop EventBaseLoop;
[EvImport] public static D.event_free EventFree;
[EvImport] public static D.event_active EventActive;
[EvImport] public static D.evconnlistener_free EvConnListenerFree;
[EvImport] public static D.evconnlistener_new_bind EvConnListenerNewBind;
[EvImport(EvDll.Core, "event_new")] public static D.event_new_windows EventNewWindows;
[EvImport(EvDll.Core, "event_new")] public static D.event_new_normal EventNewNix;
[EvImport (EvDll.Core, "evconnlistener_get_fd")] public static D.evconnlistener_get_fd_windows EvConnListenerGetFdWindows;
[EvImport(EvDll.Core, "evconnlistener_get_fd")] public static D.evconnlistener_get_fd_normal EvConnListenerGetFdNix;
[EvImport (EvDll.Core, "evconnlistener_new")] public static D.evconnlistener_new_windows EvConnListenerNewWindows;
[EvImport(EvDll.Core, "evconnlistener_new")] public static D.evconnlistener_new_normal EvConnListenerNewNix;
[EvImport(EvDll.Extra, "evhttp_accept_socket_with_handle")] public static D.evhttp_accept_socket_with_handle_windows EvHttpAcceptSocketWithHandleWindows;
[EvImport(EvDll.Extra, "evhttp_accept_socket_with_handle")] public static D.evhttp_accept_socket_with_handle_normal EvHttpAcceptSocketWithHandleNix;
[EvImport(EvDll.Extra)] public static D.evhttp_bind_listener EvHttpBindListener;
[EvImport(EvDll.Extra)] public static D.evhttp_free EvHttpFree;
[EvImport(EvDll.Extra)] public static D.evhttp_new EvHttpNew;
[EvImport(EvDll.Extra)] public static D.evhttp_set_gencb EvHttpSetGenCb;
[EvImport(EvDll.Extra)] public static D.evhttp_bind_socket_with_handle EvHttpBindSocketWithHandle;
[EvImport(EvDll.Extra)] public static D.evhttp_del_accept_socket EvHttpDelAcceptSocket;
[EvImport(EvDll.Extra)] public static D.evhttp_send_reply EvHttpSendReply;
[EvImport(EvDll.Extra)] public static D.evhttp_set_allowed_methods EvHttpSetAllowedMethods;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_command EvHttpRequestGetCommand;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_connection EvHttpRequestGetConnection;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_uri EvHttpRequestGetUri;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_host EvHttpRequestGetHost;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_input_headers EvHttpRequestGetInputHeaders;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_input_buffer EvHttpRequestGetInputBuffer;
[EvImport(EvDll.Extra)] public static D.evhttp_request_get_output_headers EvHttpRequestGetOutputHeaders;
[EvImport(EvDll.Extra)] public static D.evhttp_connection_get_peer EvHttpConnectionGetPeer;
[EvImport(EvDll.Extra)] public static D.evhttp_add_header EvHttpAddHeader;
[EvImport(EvDll.Extra)] public static D.evhttp_add_virtual_host EvHttpAddVirtualHost;
[EvImport(EvDll.Extra)] public static D.evhttp_remove_virtual_host EvHttpRemoveVirtualHost;
[EvImport(EvDll.Extra)] public static D.evhttp_add_server_alias EvHttpAddServerAlias;
[EvImport(EvDll.Extra)] public static D.evhttp_remove_server_alias EvHttpRemoveServerAlias;
public static EvHttpBoundSocket EvHttpAcceptSocketWithHandle(EvHttp http, IntPtr fd)
{
return Platform.RunningOnWindows ? EvHttpAcceptSocketWithHandleWindows(http, fd) : EvHttpAcceptSocketWithHandleNix(http, fd.ToInt32());
}
public static EvConnListener EvConnListenerNew(EventBase evBase, IntPtr cb, IntPtr ptr, uint flags, int backlog, IntPtr fd)
{
return Platform.RunningOnWindows
? EvConnListenerNewWindows(evBase, cb, ptr, flags, backlog, fd)
: EvConnListenerNewNix(evBase, cb, ptr, flags, backlog, fd.ToInt32());
}
public static event Action<int, string> Log;
private static readonly D.log_cb LogCallbackDelegate = LogCallback;
static void LogCallback(int sev, IntPtr message)
{
var msg = Marshal.PtrToStringAnsi(message);
if (Log != null)
Log(sev, msg);
else
Console.WriteLine(msg);
}
[DllImport("Ws2_32.dll")]
static extern int WSAStartup(ushort wVersionRequested, byte[] data);
public static void Init (string basePath = null)
{
var platform = Environment.OSVersion.Platform;
if (platform == PlatformID.Unix && File.Exists("/usr/lib/libSystem.dylib"))
platform = PlatformID.MacOSX;
IDynLoader loader;
switch (platform)
{
case PlatformID.Win32NT:
WSAStartup(514, new byte[512]);
loader = new Win32Loader();
break;
case PlatformID.Unix:
loader = new LinuxLoader();
break;
case PlatformID.MacOSX:
loader = new OsxLoader();
break;
default:
throw new NotSupportedException("Platform " + platform + " is not supported.");
}
var core = loader.LoadLibrary(basePath, "libevent_core");
var extra = loader.LoadLibrary(basePath, "libevent_extra");
foreach (var fieldInfo in typeof (Event).GetFields(BindingFlags.Static | BindingFlags.Public))
{
if (!typeof (Delegate).IsAssignableFrom(fieldInfo.FieldType))
continue;
var import = fieldInfo.GetCustomAttributes (typeof (EvImportAttribute), true).Cast<EvImportAttribute> ().First ();
var lib = import.Dll == EvDll.Core ? core : extra;
var funcPtr = loader.GetProcAddress(lib, import.Name ?? fieldInfo.FieldType.Name);
fieldInfo.SetValue(null, Marshal.GetDelegateForFunctionPointer(funcPtr, fieldInfo.FieldType));
}
EventSetLogCallback(LogCallbackDelegate);
var selectorPtr = platform == PlatformID.Win32NT
? loader.GetProcAddress(core, "evthread_use_windows_threads")
: loader.GetProcAddress(loader.LoadLibrary(basePath, "libevent_pthreads"), "evthread_use_pthreads");
((D.thread_model_selector) Marshal.GetDelegateForFunctionPointer(selectorPtr, typeof (D.thread_model_selector)))();
}
}
}