Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
222 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Runtime.InteropServices; | ||
using System.Threading.Tasks; | ||
using EvHttpSharp.Interop; | ||
|
||
namespace EvHttpSharp | ||
{ | ||
public class EventHttpMultiworkerListener : IEventHttpListener | ||
{ | ||
private readonly List<EventHttpListener> _workers = new List<EventHttpListener>(); | ||
private readonly EventHttpListener.RequestCallback _cb; | ||
private readonly int _workerCount; | ||
private IntPtr _ownedFileDescriptor; | ||
|
||
|
||
public EventHttpMultiworkerListener(EventHttpListener.RequestCallback cb, int workers) | ||
{ | ||
if (workers < 1) | ||
throw new ArgumentException("Invalid number of workers"); | ||
_cb = cb; | ||
_workerCount = workers; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_workers.ForEach(x => x.Dispose()); | ||
if (_ownedFileDescriptor != IntPtr.Zero) | ||
{ | ||
Platform.CloseFileDescriptor(_ownedFileDescriptor); | ||
_ownedFileDescriptor = IntPtr.Zero; | ||
} | ||
} | ||
|
||
void CheckAlreadyListening() | ||
{ | ||
if (_workers.Count != 0) | ||
throw new InvalidOperationException("Already listening"); | ||
} | ||
|
||
public void Start(string host, ushort port) | ||
{ | ||
var soaddr = new Event.sockaddr_in | ||
{ | ||
sin_family = Event.AF_INET, | ||
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)port), | ||
sin_addr = 0, | ||
sin_zero = new byte[8] | ||
}; | ||
|
||
using (var evBase = Event.EventBaseNew()) | ||
using ( | ||
var listener = Event.EvConnListenerNewBind(evBase, IntPtr.Zero, IntPtr.Zero, 1u << 3, 256, ref soaddr, | ||
Marshal.SizeOf(soaddr))) | ||
{ | ||
if (listener.IsInvalid) | ||
throw new IOException("Unable to bind socket"); | ||
_ownedFileDescriptor = listener.FileDescriptor; | ||
} | ||
Start(_ownedFileDescriptor); | ||
|
||
} | ||
|
||
public void Start(IntPtr sharedSocket) | ||
{ | ||
_workers.AddRange(Enumerable.Repeat(0, _workerCount).Select(_ => new EventHttpListener(_cb))); | ||
_workers.ForEach(w => w.Start(sharedSocket)); | ||
} | ||
|
||
private Task Aggregate(IEnumerable<Task> tasks) | ||
{ | ||
var ta = tasks.ToArray(); | ||
return Task.Factory.ContinueWhenAll(ta.ToArray(), results => | ||
{ | ||
var exceptions = results.Where(r => r.IsFaulted).Select(r => r.Exception).Cast<Exception>().ToArray(); | ||
if (exceptions.Length != 0) | ||
throw new AggregateException(exceptions); | ||
}); | ||
} | ||
|
||
public Task StopListeningAsync() | ||
{ | ||
return Aggregate(_workers.Select(x => x.StopListeningAsync())); | ||
} | ||
|
||
public Task WaitForPendingConnections() | ||
{ | ||
return Aggregate(_workers.Select(x => x.WaitForPendingConnections())); | ||
} | ||
|
||
public Task Shutdown() | ||
{ | ||
return Aggregate(_workers.Select(w => w.Shutdown())); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
namespace EvHttpSharp | ||
{ | ||
public interface IEventHttpListener : IDisposable | ||
{ | ||
void Start(string host, ushort port); | ||
void Start(IntPtr sharedSocket); | ||
Task StopListeningAsync(); | ||
Task WaitForPendingConnections(); | ||
Task Shutdown(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
|
||
namespace EvHttpSharp.Interop | ||
{ | ||
static class Platform | ||
{ | ||
public static readonly bool RunningOnWindows = Path.DirectorySeparatorChar == '\\'; | ||
|
||
[DllImport("libc", EntryPoint = "close")] | ||
private static extern void Close(int fd); | ||
|
||
[DllImport("kernel32.dll")] | ||
private static extern void CloseHandle(IntPtr hFile); | ||
|
||
public static void CloseFileDescriptor(IntPtr hFile) | ||
{ | ||
if (RunningOnWindows) | ||
CloseHandle(hFile); | ||
else | ||
Close(hFile.ToInt32()); | ||
} | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters