├── .gitignore
├── .gitmodules
├── LICENSE
├── Makefile
├── README.md
├── msbuildpath.exe
├── src
├── Libuv.Tests
│ ├── Libuv.Tests.csproj
│ └── webserver.cs
├── Libuv.sln
└── Libuv
│ ├── CheckWatcher.cs
│ ├── ChildProcess.cs
│ ├── IdleWatcher.cs
│ ├── Libuv.csproj
│ ├── PipeServer.cs
│ ├── PipeSocket.cs
│ ├── PrepareWatcher.cs
│ ├── TcpServer.cs
│ ├── TcpSocket.cs
│ ├── TimerWatcher.cs
│ ├── UV.cs
│ ├── UVStream.cs
│ └── Watcher.cs
└── winbuild.bat
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "libuv"]
2 | path = deps/libuv
3 | url = git://github.com/joyent/libuv.git
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011 Kerry Snyder
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #####
2 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
3 |
4 | CSBUILD=xbuild
5 | UVFLAGS=CPPFLAGS="-m32"
6 | CC=$(PREFIX)gcc
7 |
8 | STATIC_LIBRARY=so
9 |
10 | ifeq (Darwin,$(uname_S))
11 | STATIC_LIBRARY=dylib
12 | endif
13 |
14 | so=-shared
15 | dylib=-dynamiclib -framework CoreServices
16 | #####
17 | TEST_DIRS = src/Libuv.Tests
18 | TEST_DEPS := $(foreach dir, $(TEST_DIRS), $(wildcard $(dir)/*))
19 | LIBUV_DIRS = src/Libuv
20 | LIBUV_DEPS := $(foreach dir, $(LIBUV_DIRS), $(wildcard $(dir)/*))
21 |
22 | all: build/Libuv.Tests.exe
23 |
24 | build/Libuv.dll: build/libuv.$(STATIC_LIBRARY) $(LIBUV_DEPS)
25 | $(CSBUILD) src/Libuv.sln /target:Libuv
26 |
27 | build/Libuv.Tests.exe: build/Libuv.dll $(TEST_DEPS)
28 | $(CSBUILD) src/Libuv.sln
29 |
30 | deps/libuv/uv.a:
31 | mkdir build/
32 | $(UVFLAGS) $(MAKE) -C deps/libuv
33 |
34 | build/libuv.%: deps/libuv/uv.a
35 | ar -x deps/libuv/uv.a
36 | $(CC) $($(STATIC_LIBRARY)) -m32 -o build/libuv.$(STATIC_LIBRARY) *.o
37 | rm -rf __.SYMDEF\ SORTED *.o
38 |
39 | clean:
40 | $(RM) -r build/
41 | $(MAKE) -C deps/libuv clean
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | libuv-sharp
2 | ==========
3 |
4 | What
5 | ----
6 |
7 | C# bindings to [libuv][0]... that's about it. Ultimate goal is to provide really good cross-platform evented sockets for [manos][1].
8 |
9 | Status
10 | -----
11 |
12 | Builds and runs on Windows, Mac and Linux.
13 |
14 | Requirements
15 | ------------
16 |
17 | ### *nixes
18 |
19 | * [Mono][2] (Tested under 2.10.2)
20 | * gcc
21 |
22 | ### Windows
23 |
24 | * MSVC 2010 (Not tested with the express edition, but it should work)
25 | * MSVC# 2010
26 |
27 | Build and Run
28 | -------------
29 |
30 | ### Get it
31 |
32 | git pull git://github.com/kersny/libuv-csharp.git
33 | git submodule update --init
34 |
35 | ### *nixes
36 |
37 | make
38 | mono build/Libuv.Tests.exe
39 | (to clean) make clean
40 |
41 | ### Windows
42 |
43 | winbuild.bat
44 | cd build
45 | Libuv.Tests.exe
46 | (to clean) winbuild.bat clean
47 |
48 |
49 |
50 | Somewhere else:
51 |
52 | telnet localhost 8080
53 |
54 |
55 | TODO
56 | ----
57 |
58 | * Test for Memory Leaks
59 | * Fix Child Processes
60 | * Proper test suite to make bumping UV Version easier
61 | * Auto-generated struct sizes for all platforms
62 |
63 | [0]: https://www.github.com/joyent/libuv
64 | [1]: https://www.github.com/jacksonh/manos
65 | [2]: http://www.go-mono.com/mono-downloads/download.html
66 |
--------------------------------------------------------------------------------
/msbuildpath.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kersny/libuv-csharp/003229328bc05ce3143c2a20c22f23524efeda5d/msbuildpath.exe
--------------------------------------------------------------------------------
/src/Libuv.Tests/Libuv.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.21022
7 | 2.0
8 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}
9 | Exe
10 | Libuv
11 | Libuv.Tests
12 | v4.0
13 | ../../build/tmp/
14 |
15 |
16 | true
17 | full
18 | false
19 | ../../build/
20 | DEBUG
21 | prompt
22 | 4
23 | false
24 | true
25 | 1591
26 | x86
27 |
28 |
29 | none
30 | false
31 | ../../build/
32 | prompt
33 | 4
34 | false
35 | true
36 | 1591
37 | x86
38 |
39 |
40 |
41 |
42 | Libuv
43 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/Libuv.Tests/webserver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.IO;
4 | using System.Net;
5 | using Libuv;
6 |
7 | namespace Libuv.Tests {
8 | class webserver {
9 | [DllImport ("uv")]
10 | public static extern void uv_init ();
11 | [DllImport ("uv")]
12 | public static extern void uv_run ();
13 | static int clientcount = 0;
14 | static void Main ()
15 | {
16 | var endpoint = new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1}), 8081);
17 | uv_init();
18 |
19 | var watch = new PrepareWatcher(() => {
20 | //Console.WriteLine("Prepare Watcher Called");
21 | });
22 | watch.Start();
23 | var server = new TcpServer((socket) => {
24 | clientcount++;
25 | socket.Stream.Write(System.Text.Encoding.ASCII.GetBytes(clientcount.ToString()), 1);
26 | if (clientcount > 5) {
27 | socket.Close();
28 | }
29 | Console.WriteLine("Client Connected");
30 | socket.Stream.OnRead += (data) => {
31 | Console.WriteLine("Data Recieved: {0}", System.Text.Encoding.ASCII.GetString(data, 0, data.Length));
32 | socket.Stream.Write(data, data.Length);
33 | };
34 | //socket.OnClose += () => {
35 | // Console.WriteLine("Client Disconnected");
36 | //};
37 | });
38 | server.Listen(endpoint);
39 | var client = new TcpSocket();
40 | client.Connect(endpoint, () => {
41 | client.Stream.OnRead += (data) => {
42 | Console.WriteLine("Client Recieved: {0}", System.Text.Encoding.ASCII.GetString(data, 0, data.Length));
43 | watch.Stop();
44 | watch.Dispose();
45 | client.Close();
46 | };
47 | byte[] message = System.Text.Encoding.ASCII.GetBytes("Hello World\n");
48 | client.Stream.Write(message, message.Length);
49 | });
50 | var pipeserver = new PipeServer((socket) => {
51 | clientcount++;
52 | socket.Stream.Write(System.Text.Encoding.ASCII.GetBytes(clientcount.ToString()), 1);
53 | if (clientcount > 5) {
54 | socket.Close();
55 | }
56 | Console.WriteLine("Pipe Client Connected");
57 | socket.Stream.OnRead += (data) => {
58 | Console.WriteLine("Pipe Data Recieved: {0}", System.Text.Encoding.ASCII.GetString(data, 0, data.Length));
59 | socket.Stream.Write(data, data.Length);
60 | };
61 | //socket.OnClose += () => {
62 | // Console.WriteLine("Client Disconnected");
63 | //};
64 | });
65 | pipeserver.Listen("libuv-csharp");
66 | var pipeclient = new PipeSocket();
67 | pipeclient.Connect("libuv-csharp", () => {
68 | pipeclient.Stream.OnRead += (data) => {
69 | Console.WriteLine("Pipe Client Recieved: {0}", System.Text.Encoding.ASCII.GetString(data, 0, data.Length));
70 | watch.Stop();
71 | watch.Dispose();
72 | pipeclient.Close();
73 | };
74 | byte[] message = System.Text.Encoding.ASCII.GetBytes("Hello World\n");
75 | pipeclient.Stream.Write(message, message.Length);
76 | });
77 | var watch2 = new PrepareWatcher(() => {
78 | //Console.WriteLine("Prepare Watcher 2 Called");
79 | });
80 | watch2.Start();
81 | var check = new CheckWatcher(() => {
82 | //Console.WriteLine("Check Watcher Called");
83 | });
84 | check.Start();
85 | var idle = new IdleWatcher(() => {
86 | //Console.WriteLine("Idle Watcher Called");
87 | });
88 | idle.Start();
89 | var after = new TimerWatcher(new TimeSpan(0,0,5), new TimeSpan(1,0,0), () => {
90 | //Console.WriteLine("After 5 Seconds");
91 | });
92 | after.Start();
93 | var every = new TimerWatcher(new TimeSpan(0,0,5), () => {
94 | //Console.WriteLine("Every 5 Seconds");
95 | // after.Stop();
96 | });
97 | every.Start();
98 | var cp = new ChildProcess("ls");
99 | cp.Spawn();
100 | uv_run();
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Libuv.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 11.00
2 | # Visual Studio 2010
3 | Project("{13C31A1D-9AA8-43D7-BAEA-B9F4E9DE202B}") = "Libuv", "Libuv\Libuv.csproj", "{2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}"
4 | EndProject
5 | Project("{966921C3-BDCB-4030-9D41-5BBF59887EC2}") = "Libuv.Tests", "Libuv.Tests\Libuv.Tests.csproj", "{26D063C9-1C31-4D02-87DC-B92C8FA5952E}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Debug|Mixed Platforms = Debug|Mixed Platforms
11 | Debug|Win32 = Debug|Win32
12 | Release|Any CPU = Release|Any CPU
13 | Release|Mixed Platforms = Release|Mixed Platforms
14 | Release|Win32 = Release|Win32
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
20 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
21 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Debug|Win32.ActiveCfg = Debug|Any CPU
22 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
25 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
26 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}.Release|Win32.ActiveCfg = Release|Any CPU
27 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
30 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
31 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Debug|Win32.ActiveCfg = Debug|Any CPU
32 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
35 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
36 | {26D063C9-1C31-4D02-87DC-B92C8FA5952E}.Release|Win32.ActiveCfg = Release|Any CPU
37 | EndGlobalSection
38 | EndGlobal
39 |
--------------------------------------------------------------------------------
/src/Libuv/CheckWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Libuv {
5 | public class CheckWatcher : Watcher {
6 | [DllImport("uv")]
7 | internal static extern int uv_check_init(IntPtr check);
8 | [DllImport("uv")]
9 | internal static extern int uv_check_start(IntPtr check, uv_watcher_cb cb);
10 | [DllImport("uv")]
11 | internal static extern int uv_check_stop(IntPtr check);
12 |
13 | public CheckWatcher(Action callback) : base(callback, Sizes.CheckWatcher) {}
14 |
15 | internal override int InitImpl()
16 | {
17 | return uv_check_init(this._handle);
18 | }
19 | internal override int StartImpl()
20 | {
21 | return uv_check_start(this._handle, StaticCallback);
22 | }
23 | internal override int StopImpl()
24 | {
25 | return uv_check_stop(this._handle);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Libuv/ChildProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.IO;
4 | using System.Collections.Generic;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Libuv {
8 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
9 | public delegate void uv_exit_cb(IntPtr handle, int exit_status, int term_signal);
10 | [StructLayout(LayoutKind.Sequential)]
11 | public struct uv_process_options_t {
12 | public uv_exit_cb exit_cb;
13 | public string file;
14 | public IntPtr[] args;
15 | public IntPtr[] env;
16 | public string cwd;
17 | public int windows_verbatim_arguments;
18 |
19 | public IntPtr stdin_stream;
20 | public IntPtr stdout_stream;
21 | public IntPtr stderr_stream;
22 | }
23 | public class ChildProcess {
24 | [DllImport ("uv")]
25 | public static extern int uv_spawn(IntPtr process, uv_process_options_t options);
26 | [DllImport ("uv")]
27 | public static extern int uv_process_kill(IntPtr process, int signum);
28 | [DllImport ("uv")]
29 | public static extern int uv_pipe_init(IntPtr pipe);
30 | [DllImport ("uv")]
31 | public static extern int uv_close(IntPtr process, uv_close_cb cb);
32 | static void static_exit(IntPtr handle, int exit_status, int term_signal)
33 | {
34 | uv_close(handle, static_close);
35 | }
36 | static void static_close(IntPtr handle)
37 | {
38 | Marshal.FreeHGlobal(handle);
39 | }
40 | public string File { get; set; }
41 | public string CurrentWorkingDirectory { get; set; }
42 | public List Environment { get; private set; }
43 | public List Arguments { get; private set; }
44 | private IntPtr _handle;
45 | public UVStream StdOut;
46 | public UVStream StdErr;
47 | private IntPtr _stdout;
48 | private IntPtr _stderr;
49 | //public event Action OnExit;
50 | //private void HandleExit(string stdout, string stderr);
51 |
52 | public ChildProcess(string command)
53 | {
54 | this.File = command;
55 | this.CurrentWorkingDirectory = Directory.GetCurrentDirectory();
56 | this._stdout = Marshal.AllocHGlobal(Sizes.PipeT);
57 | uv_pipe_init(_stdout);
58 | this.StdOut = new UVStream(_stdout);
59 | this._stderr = Marshal.AllocHGlobal(Sizes.PipeT);
60 | uv_pipe_init(_stdout);
61 | this.StdOut = new UVStream(_stdout);
62 | this._handle = Marshal.AllocHGlobal(Sizes.ProcessT);
63 | }
64 | public void Spawn()
65 | {
66 | var options = new uv_process_options_t();
67 | options.exit_cb = static_exit;
68 | options.file = this.File;
69 | var args = new IntPtr[Arguments.Count + 3];
70 | args[0] = Marshal.StringToHGlobalAuto(this.CurrentWorkingDirectory);
71 | args[1] = Marshal.StringToHGlobalAuto(this.File);
72 | args[args.Length - 1] = IntPtr.Zero;
73 | for (int i = 0; i < Arguments.Count; i++)
74 | {
75 | args[i + 2] = Marshal.StringToHGlobalAuto(Arguments[i]);
76 | }
77 | options.args = args;
78 | var env = new IntPtr[Environment.Count + 1];
79 | env[Environment.Count - 1] = IntPtr.Zero;
80 | for (int i = 0; i < Environment.Count; i++)
81 | {
82 | env[i] = Marshal.StringToHGlobalAuto(Environment[i]);
83 | }
84 | options.env = env;
85 | options.stdout_stream = _stdout;
86 | options.stderr_stream = _stderr;
87 | Util.CheckError(uv_spawn(_handle, options));
88 | StdOut.ReadStart();
89 | StdErr.ReadStart();
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Libuv/IdleWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Libuv {
5 | public class IdleWatcher : Watcher {
6 | [DllImport("uv")]
7 | internal static extern int uv_idle_init(IntPtr idle);
8 | [DllImport("uv")]
9 | internal static extern int uv_idle_start(IntPtr idle, uv_watcher_cb cb);
10 | [DllImport("uv")]
11 | internal static extern int uv_idle_stop(IntPtr idle);
12 |
13 | public IdleWatcher(Action callback) : base(callback, Sizes.IdleWatcher) {}
14 |
15 | internal override int InitImpl()
16 | {
17 | return uv_idle_init(this._handle);
18 | }
19 | internal override int StartImpl()
20 | {
21 | return uv_idle_start(this._handle, StaticCallback);
22 | }
23 | internal override int StopImpl()
24 | {
25 | return uv_idle_stop(this._handle);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Libuv/Libuv.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.21022
7 | 2.0
8 | {2548B25A-2E1F-4E21-BC43-7E39B1F6F23F}
9 | library
10 | Libuv
11 | Libuv
12 | v4.0
13 | ../../build/tmp
14 |
15 |
16 | true
17 | full
18 | false
19 | ../../build
20 | DEBUG
21 | prompt
22 | 4
23 | false
24 | true
25 | 1591
26 | x86
27 |
28 |
29 | none
30 | false
31 | ../../build
32 | prompt
33 | 4
34 | false
35 | true
36 | 1591
37 | x86
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/Libuv/PipeServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Libuv {
6 | public class PipeServer {
7 | [DllImport("uv")]
8 | internal static extern int uv_pipe_init(IntPtr prepare);
9 | [DllImport("uv")]
10 | internal static extern int uv_pipe_bind(IntPtr prepare, string name);
11 | [DllImport("uv")]
12 | internal static extern int uv_listen(IntPtr stream, int backlog, uv_connection_cb cb);
13 |
14 | private static uv_connection_cb unmanaged_callback;
15 |
16 | static PipeServer()
17 | {
18 | unmanaged_callback = StaticCallback;
19 | }
20 |
21 | private Action callback;
22 | private IntPtr _handle;
23 | private GCHandle me;
24 |
25 | public PipeServer(Action callback)
26 | {
27 | this.callback = callback;
28 | this._handle = Marshal.AllocHGlobal(Sizes.PipeT);
29 | Util.CheckError(uv_pipe_init(this._handle));
30 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
31 | this.me = GCHandle.Alloc(this);
32 | handle.data = GCHandle.ToIntPtr(this.me);
33 | Marshal.StructureToPtr(handle, this._handle, true);
34 | }
35 | public void Listen(string endpoint)
36 | {
37 | Util.CheckError(uv_pipe_bind(this._handle, endpoint));
38 | Util.CheckError(uv_listen(this._handle, 128, unmanaged_callback));
39 | }
40 | public static void StaticCallback(IntPtr server_ptr, int status)
41 | {
42 | Util.CheckError(status);
43 | var handle = (uv_handle_t)Marshal.PtrToStructure(server_ptr, typeof(uv_handle_t));
44 | var instance = GCHandle.FromIntPtr(handle.data);
45 | var server = (PipeServer)instance.Target;
46 | server.callback(new PipeSocket(server._handle));
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Libuv/PipeSocket.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Libuv {
6 | public class PipeSocket {
7 | public UVStream Stream { get; private set; }
8 | static void unmanaged_connect_cb(IntPtr connection, int status)
9 | {
10 | Util.CheckError(status);
11 | var tmp = (uv_connect_t)Marshal.PtrToStructure(connection, typeof(uv_connect_t));
12 | var handle = (uv_handle_t)Marshal.PtrToStructure(tmp.handle, typeof(uv_handle_t));
13 | var instance = GCHandle.FromIntPtr(handle.data);
14 | var socket_instance = (PipeSocket)instance.Target;
15 | socket_instance.Stream = new UVStream(socket_instance._handle);
16 | socket_instance.Stream.ReadStart();
17 | socket_instance.HandleConnect();
18 | }
19 | static void on_close(IntPtr socket)
20 | {
21 | /*
22 | var handle = (uv_handle_t)Marshal.PtrToStructure(socket, typeof(uv_handle_t));
23 | var instance = GCHandle.FromIntPtr(handle.data);
24 | var watcher_instance = (PipeSocket)instance.Target;
25 | //dont think this is what should happen here
26 | watcher_instance.me.Free();
27 | Marshal.FreeHGlobal(socket);
28 | */
29 | }
30 | private IntPtr _handle;
31 | public event Action OnConnect;
32 | private GCHandle me;
33 | private IntPtr connection;
34 | public PipeSocket()
35 | {
36 | this._handle = Marshal.AllocHGlobal(Sizes.PipeT);
37 | Util.CheckError(uv_pipe_init(this._handle));
38 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
39 | this.me = GCHandle.Alloc(this);
40 | handle.data = GCHandle.ToIntPtr(this.me);
41 | Marshal.StructureToPtr(handle, this._handle, true);
42 | this.connection = Marshal.AllocHGlobal(Sizes.ConnectT);
43 | //can't attach anything to connect_t, it would get nulled
44 | }
45 | public void Connect(string path, Action OnConnect)
46 | {
47 | Util.CheckError(uv_pipe_connect(this.connection, this._handle, path, unmanaged_connect_cb));
48 | this.OnConnect += OnConnect;
49 | }
50 | public PipeSocket(IntPtr ServerHandle)
51 | {
52 | this._handle = Marshal.AllocHGlobal(Sizes.PipeT);
53 | Util.CheckError(uv_pipe_init(this._handle));
54 | Util.CheckError(uv_accept(ServerHandle, this._handle));
55 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
56 | this.me = GCHandle.Alloc(this);
57 | handle.data = GCHandle.ToIntPtr(this.me);
58 | Marshal.StructureToPtr(handle, this._handle, true);
59 | this.Stream = new UVStream(this._handle);
60 | }
61 | private void HandleConnect()
62 | {
63 | if (OnConnect != null)
64 | {
65 | OnConnect();
66 | }
67 | }
68 | public void Close()
69 | {
70 | uv_close(this._handle, on_close);
71 | }
72 | [DllImport("uv")]
73 | internal static extern int uv_pipe_init(IntPtr prepare);
74 | [DllImport ("uv")]
75 | internal static extern int uv_accept(IntPtr socket, IntPtr stream);
76 | [DllImport ("uv")]
77 | internal static extern int uv_close(IntPtr handle, uv_close_cb cb);
78 | [DllImport ("uv")]
79 | internal static extern int uv_pipe_connect(IntPtr connect, IntPtr tcp_handle, string path, uv_connect_cb cb);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Libuv/PrepareWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Libuv {
5 | public class PrepareWatcher : Watcher {
6 | [DllImport("uv")]
7 | internal static extern int uv_prepare_init(IntPtr prepare);
8 | [DllImport("uv")]
9 | internal static extern int uv_prepare_start(IntPtr prepare, uv_watcher_cb cb);
10 | [DllImport("uv")]
11 | internal static extern int uv_prepare_stop(IntPtr prepare);
12 |
13 | public PrepareWatcher(Action callback) : base(callback, Sizes.PrepareWatcher) {}
14 |
15 | internal override int InitImpl()
16 | {
17 | return uv_prepare_init(this._handle);
18 | }
19 | internal override int StartImpl()
20 | {
21 | return uv_prepare_start(this._handle, StaticCallback);
22 | }
23 | internal override int StopImpl()
24 | {
25 | return uv_prepare_stop(this._handle);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Libuv/TcpServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Libuv {
6 | public class TcpServer {
7 | [DllImport("uv")]
8 | internal static extern int uv_tcp_init(IntPtr prepare);
9 | [DllImport("uv")]
10 | internal static extern int uv_tcp_bind(IntPtr prepare, sockaddr_in address);
11 | [DllImport("uv")]
12 | internal static extern int uv_listen(IntPtr stream, int backlog, uv_connection_cb cb);
13 | [DllImport("uv")]
14 | internal static extern sockaddr_in uv_ip4_addr(string ip, int port);
15 |
16 | private static uv_connection_cb unmanaged_callback;
17 |
18 | static TcpServer()
19 | {
20 | unmanaged_callback = StaticCallback;
21 | }
22 |
23 | private Action callback;
24 | private IntPtr _handle;
25 | private GCHandle me;
26 |
27 | public TcpServer(Action callback)
28 | {
29 | this.callback = callback;
30 | this._handle = Marshal.AllocHGlobal(Sizes.TcpT);
31 | Util.CheckError(uv_tcp_init(this._handle));
32 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
33 | this.me = GCHandle.Alloc(this);
34 | handle.data = GCHandle.ToIntPtr(this.me);
35 | Marshal.StructureToPtr(handle, this._handle, true);
36 | }
37 | public void Listen(IPEndPoint endpoint)
38 | {
39 | var info = uv_ip4_addr(endpoint.Address.ToString(), endpoint.Port);
40 | Util.CheckError(uv_tcp_bind(this._handle, info));
41 | Util.CheckError(uv_listen(this._handle, 128, unmanaged_callback));
42 | }
43 | public static void StaticCallback(IntPtr server_ptr, int status)
44 | {
45 | Util.CheckError(status);
46 | var handle = (uv_handle_t)Marshal.PtrToStructure(server_ptr, typeof(uv_handle_t));
47 | var instance = GCHandle.FromIntPtr(handle.data);
48 | var server = (TcpServer)instance.Target;
49 | server.callback(new TcpSocket(server._handle));
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Libuv/TcpSocket.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Libuv {
6 | public class TcpSocket {
7 | public UVStream Stream { get; private set; }
8 | static void unmanaged_connect_cb(IntPtr connection, int status)
9 | {
10 | Util.CheckError(status);
11 | var tmp = (uv_connect_t)Marshal.PtrToStructure(connection, typeof(uv_connect_t));
12 | var handle = (uv_handle_t)Marshal.PtrToStructure(tmp.handle, typeof(uv_handle_t));
13 | var instance = GCHandle.FromIntPtr(handle.data);
14 | var socket_instance = (TcpSocket)instance.Target;
15 | socket_instance.Stream = new UVStream(socket_instance._handle);
16 | socket_instance.Stream.ReadStart();
17 | socket_instance.HandleConnect();
18 | }
19 | static void on_close(IntPtr socket)
20 | {
21 | /*
22 | var handle = (uv_handle_t)Marshal.PtrToStructure(socket, typeof(uv_handle_t));
23 | var instance = GCHandle.FromIntPtr(handle.data);
24 | var watcher_instance = (TcpSocket)instance.Target;
25 | //dont think this is what should happen here
26 | watcher_instance.me.Free();
27 | Marshal.FreeHGlobal(socket);
28 | */
29 | }
30 | private IntPtr _handle;
31 | public event Action OnConnect;
32 | private GCHandle me;
33 | private IntPtr connection;
34 | public TcpSocket()
35 | {
36 | this._handle = Marshal.AllocHGlobal(Sizes.TcpT);
37 | Util.CheckError(uv_tcp_init(this._handle));
38 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
39 | this.me = GCHandle.Alloc(this);
40 | handle.data = GCHandle.ToIntPtr(this.me);
41 | Marshal.StructureToPtr(handle, this._handle, true);
42 | this.connection = Marshal.AllocHGlobal(Sizes.ConnectT);
43 | //can't attach anything to connect_t, it would get nulled
44 | }
45 | public void Connect(IPEndPoint endpoint, Action OnConnect)
46 | {
47 | var info = uv_ip4_addr(endpoint.Address.ToString(), endpoint.Port);
48 | Util.CheckError(uv_tcp_connect(this.connection, this._handle, info, unmanaged_connect_cb));
49 | this.OnConnect += OnConnect;
50 | }
51 | public TcpSocket(IntPtr ServerHandle)
52 | {
53 | this._handle = Marshal.AllocHGlobal(Sizes.TcpT);
54 | Util.CheckError(uv_tcp_init(this._handle));
55 | Util.CheckError(uv_accept(ServerHandle, this._handle));
56 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
57 | this.me = GCHandle.Alloc(this);
58 | handle.data = GCHandle.ToIntPtr(this.me);
59 | Marshal.StructureToPtr(handle, this._handle, true);
60 | this.Stream = new UVStream(this._handle);
61 | }
62 | private void HandleConnect()
63 | {
64 | if (OnConnect != null)
65 | {
66 | OnConnect();
67 | }
68 | }
69 | public void Close()
70 | {
71 | uv_close(this._handle, on_close);
72 | }
73 | [DllImport("uv")]
74 | internal static extern int uv_tcp_init(IntPtr prepare);
75 | [DllImport ("uv")]
76 | internal static extern int uv_accept(IntPtr socket, IntPtr stream);
77 | [DllImport ("uv")]
78 | internal static extern int uv_close(IntPtr handle, uv_close_cb cb);
79 | [DllImport ("uv")]
80 | internal static extern int uv_tcp_connect(IntPtr connect, IntPtr tcp_handle, sockaddr_in address, uv_connect_cb cb);
81 | [DllImport ("uv")]
82 | internal static extern sockaddr_in uv_ip4_addr(string ip, int port);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Libuv/TimerWatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Libuv {
5 | public class TimerWatcher : Watcher {
6 | [DllImport("uv")]
7 | internal static extern int uv_timer_init(IntPtr timer);
8 | [DllImport("uv")]
9 | internal static extern int uv_timer_start(IntPtr timer, uv_watcher_cb cb, double after, double repeat);
10 | [DllImport("uv")]
11 | internal static extern int uv_timer_stop(IntPtr timer);
12 | [DllImport("uv")]
13 | internal static extern int uv_timer_again(IntPtr timer);
14 | [DllImport("uv")]
15 | internal static extern int uv_timer_set_repeat(IntPtr timer, double time);
16 |
17 | private TimeSpan delay;
18 | private TimeSpan repeat;
19 | public TimeSpan Repeat {
20 | get { return repeat; }
21 | set {
22 | if (value < TimeSpan.Zero)
23 | throw new ArgumentException("value");
24 | repeat = value;
25 | Util.CheckError(uv_timer_set_repeat(this._handle, repeat.TotalMilliseconds));
26 | }
27 | }
28 | public TimerWatcher(TimeSpan repeat, Action callback)
29 | : this (TimeSpan.Zero, repeat, callback)
30 | {
31 | }
32 | public TimerWatcher(TimeSpan after, TimeSpan repeat, Action callback) : base(callback, Sizes.TimerWatcher)
33 | {
34 | this.repeat = repeat;
35 | this.delay = after;
36 |
37 | }
38 | internal override int InitImpl()
39 | {
40 | return uv_timer_init(this._handle);
41 | }
42 | internal override int StartImpl()
43 | {
44 | return uv_timer_start(this._handle, StaticCallback, delay.TotalMilliseconds, repeat.TotalMilliseconds);
45 | }
46 | internal override int StopImpl()
47 | {
48 | return uv_timer_stop(this._handle);
49 | }
50 | public void Again()
51 | {
52 | Util.CheckError(uv_timer_again(this._handle));
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Libuv/UV.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Libuv {
6 | public static class Util {
7 | public static void CheckError(int code)
8 | {
9 | if (code != 0) throw new Exception(uv_strerror(uv_last_error()));
10 | }
11 | [DllImport ("uv")]
12 | public static extern uv_err_t uv_last_error();
13 | [DllImport ("uv")]
14 | public static extern string uv_strerror(uv_err_t err);
15 | }
16 | [StructLayout(LayoutKind.Sequential)]
17 | public struct uv_handle_t {
18 | public uv_handle_type type;
19 | public IntPtr close_cb;
20 | public IntPtr data;
21 | }
22 | [StructLayout(LayoutKind.Sequential)]
23 | public struct uv_req_t {
24 | public uv_req_type type;
25 | public IntPtr data;
26 | }
27 | [StructLayout(LayoutKind.Sequential)]
28 | public struct uv_connect_t {
29 | public uv_req_type type;
30 | public IntPtr data;
31 | #if !__MonoCS__
32 | NativeOverlapped overlapped;
33 | IntPtr queued_bytes;
34 | uv_err_t error;
35 | IntPtr next_req;
36 | #endif
37 | public IntPtr cb;
38 | public IntPtr handle;
39 | }
40 | [StructLayout(LayoutKind.Sequential)]
41 | public struct uv_shutdown_t {
42 | public uv_req_type type;
43 | public IntPtr data;
44 | #if !__MonoCS__
45 | NativeOverlapped overlapped;
46 | IntPtr queued_bytes;
47 | uv_err_t error;
48 | IntPtr next_req;
49 | #endif
50 | public IntPtr handle;
51 | public IntPtr cb;
52 | }
53 | [StructLayout(LayoutKind.Sequential)]
54 | public struct uv_err_t
55 | {
56 | public uv_err_code code;
57 | int sys_errno_;
58 | }
59 | public enum uv_err_code
60 | {
61 | UV_UNKNOWN = -1,
62 | UV_OK = 0,
63 | UV_EOF,
64 | UV_EACCESS,
65 | UV_EAGAIN,
66 | UV_EADDRINUSE,
67 | UV_EADDRNOTAVAIL,
68 | UV_EAFNOSUPPORT,
69 | UV_EALREADY,
70 | UV_EBADF,
71 | UV_EBUSY,
72 | UV_ECONNABORTED,
73 | UV_ECONNREFUSED,
74 | UV_ECONNRESET,
75 | UV_EDESTADDRREQ,
76 | UV_EFAULT,
77 | UV_EHOSTUNREACH,
78 | UV_EINTR,
79 | UV_EINVAL,
80 | UV_EISCONN,
81 | UV_EMFILE,
82 | UV_ENETDOWN,
83 | UV_ENETUNREACH,
84 | UV_ENFILE,
85 | UV_ENOBUFS,
86 | UV_ENOMEM,
87 | UV_ENONET,
88 | UV_ENOPROTOOPT,
89 | UV_ENOTCONN,
90 | UV_ENOTSOCK,
91 | UV_ENOTSUP,
92 | UV_EPROTO,
93 | UV_EPROTONOSUPPORT,
94 | UV_EPROTOTYPE,
95 | UV_ETIMEDOUT,
96 | UV_ECHARSET,
97 | UV_EAIFAMNOSUPPORT,
98 | UV_EAINONAME,
99 | UV_EAISERVICE,
100 | UV_EAISOCKTYPE,
101 | UV_ESHUTDOWN
102 | }
103 | public enum uv_handle_type {
104 | UV_UNKNOWN_HANDLE = 0,
105 | UV_TCP,
106 | UV_NAMED_PIPE,
107 | UV_TTY,
108 | UV_FILE,
109 | UV_TIMER,
110 | UV_PREPARE,
111 | UV_CHECK,
112 | UV_IDLE,
113 | UV_ASYNC,
114 | UV_ARES_TASK,
115 | UV_ARES_EVENT,
116 | UV_GETADDRINFO,
117 | UV_PROCESS
118 | }
119 | public enum uv_req_type {
120 | UV_UNKNOWN_REQ = 0,
121 | UV_CONNECT,
122 | UV_ACCEPT,
123 | UV_READ,
124 | UV_WRITE,
125 | UV_SHUTDOWN,
126 | UV_WAKEUP,
127 | UV_REQ_TYPE_PRIVATE
128 | }
129 | public static class Sizes {
130 | #if __MonoCS__
131 | public static readonly int PrepareWatcher = 64;
132 | public static readonly int IdleWatcher = 64;
133 | public static readonly int CheckWatcher = 64;
134 | public static readonly int TimerWatcher = 80;
135 | public static readonly int TcpT = 152;
136 | public static readonly int PipeT = 156;
137 | public static readonly int ShutdownT = 16;
138 | public static readonly int ConnectT = 24;
139 | public static readonly int WriteT = 68;
140 | public static readonly int ProcessT = 88;
141 | #else
142 | public static readonly int PrepareWatcher = 40;
143 | public static readonly int IdleWatcher = 40;
144 | public static readonly int CheckWatcher = 40;
145 | public static readonly int TimerWatcher = 72;
146 | public static readonly int TcpT = 436;
147 | public static readonly int ShutdownT = 52;
148 | public static readonly int ConnectT = 52;
149 | public static readonly int WriteT = 52;
150 | #endif
151 | }
152 | [StructLayout(LayoutKind.Sequential)]
153 | #if __MonoCS__
154 | public struct uv_buf_t
155 | {
156 | public IntPtr data;
157 | public IntPtr len;
158 | }
159 | #else
160 | public struct uv_buf_t
161 | {
162 | public ulong len;
163 | public IntPtr data;
164 | }
165 | #endif
166 | // From: http://www.elitepvpers.com/forum/co2-programming/159327-advanced-winsock-c.html
167 | [StructLayout(LayoutKind.Sequential, Size=16)]
168 | public struct sockaddr_in
169 | {
170 | public const int Size = 16;
171 |
172 | public short sin_family;
173 | public ushort sin_port;
174 | public struct in_addr
175 | {
176 | public uint S_addr;
177 | public struct _S_un_b
178 | {
179 | public byte s_b1, s_b2, s_b3, s_b4;
180 | }
181 | public _S_un_b S_un_b;
182 | public struct _S_un_w
183 | {
184 | public ushort s_w1, s_w2;
185 | }
186 | public _S_un_w S_un_w;
187 | }
188 | public in_addr sin_addr;
189 | }
190 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
191 | public delegate void uv_shutdown_cb(IntPtr req, int status);
192 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
193 | public delegate uv_buf_t uv_alloc_cb(IntPtr stream, IntPtr suggested_size);
194 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
195 | public delegate void uv_read_cb(IntPtr req, IntPtr nread, uv_buf_t buf);
196 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
197 | public delegate void uv_write_cb(IntPtr req, int status);
198 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
199 | public delegate void uv_connect_cb(IntPtr conn, int status);
200 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
201 | public delegate void uv_close_cb(IntPtr conn);
202 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
203 | public delegate void uv_connection_cb(IntPtr server, int status);
204 | }
205 |
--------------------------------------------------------------------------------
/src/Libuv/UVStream.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Libuv {
5 | public class UVStream {
6 | private IntPtr handle;
7 | private GCHandle gchandle;
8 | public event Action OnRead;
9 | public event Action OnClose;
10 | // Pass an already init-ed uv_handle_t subclass to stream from
11 | public UVStream(IntPtr Handle) {
12 | this.gchandle = GCHandle.Alloc(this);
13 | this.handle = Handle;
14 | //attach handle of ourself to the c struct so we can access instance callbacks in static callbacks
15 | //static callbacks are used as to not force the clr to thunk a new one for every callback on every object
16 | var handle = (uv_handle_t)Marshal.PtrToStructure(this.handle, typeof(uv_handle_t));
17 | this.gchandle = GCHandle.Alloc(this);
18 | handle.data = GCHandle.ToIntPtr(this.gchandle);
19 | Marshal.StructureToPtr(handle, this.handle, true);
20 | }
21 | // Instance Methods
22 | public void ReadStart()
23 | {
24 | Util.CheckError(uv_read_start(this.handle, static_alloc, static_read));
25 | }
26 | public void ReadStop()
27 | {
28 | Util.CheckError(uv_read_stop(this.handle));
29 | }
30 | public void Write(byte[] data, int length)
31 | {
32 | IntPtr write_request = Marshal.AllocHGlobal(Sizes.WriteT);
33 | var dataptrhandle = GCHandle.Alloc(data, GCHandleType.Pinned);
34 | // This is not being freed, which needs to be fixed
35 | IntPtr dat = dataptrhandle.AddrOfPinnedObject();
36 | uv_buf_t[] buf = new uv_buf_t[1];
37 | buf[0].data = dat;
38 | #if __MonoCS__
39 | buf[0].len = (IntPtr)length;
40 | #else
41 | buf[0].len = (ulong)length;
42 | #endif
43 | var req = (uv_req_t)Marshal.PtrToStructure(write_request, typeof(uv_req_t));
44 | req.data = dat;
45 | Marshal.StructureToPtr(req, write_request, true);
46 | Util.CheckError(uv_write(write_request, this.handle, buf, 1, after_write));
47 | }
48 | private void HandleRead(byte[] data)
49 | {
50 | if (OnRead != null)
51 | {
52 | OnRead(data);
53 | }
54 | }
55 | private void HandleClose()
56 | {
57 | if (OnClose != null)
58 | {
59 | OnClose();
60 | }
61 | }
62 | // Static Callbacks
63 | static uv_buf_t static_alloc(IntPtr tcp, IntPtr size)
64 | {
65 | uv_buf_t buf;
66 | buf.data = Marshal.AllocHGlobal((int)size);
67 | #if __MonoCS__
68 | buf.len = size;
69 | #else
70 | buf.len = (ulong)size;
71 | #endif
72 | return buf;
73 | }
74 | static void static_read(IntPtr stream, IntPtr nread, uv_buf_t buf)
75 | {
76 | int size = (int)nread;
77 | if (size < 0) {
78 | if ((int)buf.data != 0)
79 | Marshal.FreeHGlobal(buf.data);
80 | IntPtr shutdown = Marshal.AllocHGlobal(Sizes.ShutdownT);
81 | Util.CheckError(uv_shutdown(shutdown, stream, after_shutdown));
82 | return;
83 | }
84 | if (size == 0) {
85 | Marshal.FreeHGlobal(buf.data);
86 | return;
87 | }
88 | byte[] data = new byte[size];
89 | Marshal.Copy(buf.data, data, 0, size);
90 | var handle = (uv_handle_t)Marshal.PtrToStructure(stream, typeof(uv_handle_t));
91 | var instance_gchandle = GCHandle.FromIntPtr(handle.data);
92 | var stream_instance = (UVStream)instance_gchandle.Target;
93 | stream_instance.HandleRead(data);
94 | Marshal.FreeHGlobal(buf.data);
95 | }
96 | static void after_shutdown(IntPtr shutdown, int status)
97 | {
98 | Util.CheckError(status);
99 | var tmp = (uv_shutdown_t)Marshal.PtrToStructure(shutdown, typeof(uv_shutdown_t));
100 | var handle = (uv_handle_t)Marshal.PtrToStructure(tmp.handle, typeof(uv_handle_t));
101 | var instance = GCHandle.FromIntPtr(handle.data);
102 | var watcher_instance = (UVStream)instance.Target;
103 | watcher_instance.HandleClose();
104 | Marshal.FreeHGlobal(shutdown);
105 | }
106 | static void after_write(IntPtr write_req, int status)
107 | {
108 | Util.CheckError(status);
109 | var req = (uv_req_t)Marshal.PtrToStructure(write_req, typeof(uv_req_t));
110 | //var handle = GCHandle.FromIntPtr(req.data);
111 | //handle.Free();
112 | Marshal.FreeHGlobal(write_req);
113 | }
114 | // Externs
115 | [DllImport ("uv")]
116 | internal static extern int uv_read_start(IntPtr stream, uv_alloc_cb alloc_cb, uv_read_cb read);
117 | [DllImport ("uv")]
118 | internal static extern int uv_read_stop(IntPtr stream);
119 | [DllImport ("uv")]
120 | internal static extern int uv_write(IntPtr req, IntPtr handle, uv_buf_t[] bufs, int bufcnt, uv_write_cb cb);
121 | [DllImport ("uv")]
122 | internal static extern int uv_shutdown(IntPtr req, IntPtr handle, uv_shutdown_cb cb);
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/Libuv/Watcher.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System;
3 |
4 | namespace Libuv {
5 | public abstract class Watcher : IDisposable {
6 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
7 | internal delegate void uv_watcher_cb(IntPtr watcher, int status);
8 |
9 | internal Action callback;
10 | internal IntPtr _handle;
11 | internal GCHandle me;
12 |
13 | public Watcher(Action callback, int size)
14 | {
15 | this.callback = callback;
16 | this._handle = Marshal.AllocHGlobal(size);
17 | Util.CheckError(this.InitImpl());
18 | var handle = (uv_handle_t)Marshal.PtrToStructure(this._handle, typeof(uv_handle_t));
19 | this.me = GCHandle.Alloc(this);
20 | handle.data = GCHandle.ToIntPtr(this.me);
21 | Marshal.StructureToPtr(handle, this._handle, true);
22 | }
23 | internal static void StaticCallback(IntPtr watcher, int status)
24 | {
25 | Util.CheckError(status);
26 | var handle = (uv_handle_t)Marshal.PtrToStructure(watcher, typeof(uv_handle_t));
27 | var instance = GCHandle.FromIntPtr(handle.data);
28 | var watcher_instance = (Watcher)instance.Target;
29 | watcher_instance.callback();
30 | }
31 | public void Start()
32 | {
33 | Util.CheckError(this.StartImpl());
34 | }
35 | public void Stop()
36 | {
37 | Util.CheckError(this.StopImpl());
38 | }
39 |
40 | internal abstract int InitImpl();
41 | internal abstract int StartImpl();
42 | internal abstract int StopImpl();
43 |
44 | ~Watcher()
45 | {
46 | Cleanup();
47 | }
48 | private void Cleanup()
49 | {
50 | me.Free();
51 | Marshal.FreeHGlobal(this._handle);
52 | }
53 | public void Dispose()
54 | {
55 | Cleanup();
56 | GC.SuppressFinalize(this);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/winbuild.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | IF %1.==. GOTO Build
3 | IF %1==clean (
4 | GOTO Clean
5 | ) ELSE (
6 | GOTO Build
7 | )
8 | :Build
9 | del uv.def
10 | echo LIBRARY UVWRAP >> uv.def
11 | echo EXPORTS >> uv.def
12 | set count=0
13 | setlocal ENABLEDELAYEDEXPANSION
14 | for /f "tokens=1,2,3,4,5 delims=( " %%a in ('findstr "extern" src\Libuv\*.cs src\Libuv.Tests\*.cs') do (
15 | set /a count=count+1
16 | echo %%e @!count! >> uv.def
17 | )
18 | call "deps\libuv\create-msvs-files.bat"
19 | cd ../..
20 | for /f %%b IN ('msbuildpath.exe') do %%bMSBuild.exe deps\libuv\build\all.sln
21 | call "%VS100COMNTOOLS%vsvars32.bat"
22 | FOR /F %%a IN ('msbuildpath.exe') DO %%aMSBuild.exe src\Libuv.sln
23 | "%VCINSTALLDIR%bin\cl.exe" /o build\uv.dll deps\libuv\build\Debug\obj\uv\*.obj ws2_32.lib advapi32.lib /link /DLL /DEF:uv.def
24 | GOTO Done
25 | :Clean
26 | rmdir /S /Q deps\libuv\build\Debug
27 | rmdir /S /Q build
28 | del /Q uv_wrap.obj
29 | del /Q uv_wrap.def
30 | GOTO Done
31 | :Done
32 | echo on
33 |
--------------------------------------------------------------------------------