Skip to content

Commit 1e555b8

Browse files
committed
implement watchers & static callbacks
1 parent 4947c94 commit 1e555b8

File tree

7 files changed

+141
-23
lines changed

7 files changed

+141
-23
lines changed

src/Libuv.Tests/webserver.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ static void Main ()
5151
Console.WriteLine("Prepare Watcher 2 Called");
5252
});
5353
watch2.Start();
54+
var check = new CheckWatcher((ptr, stat) => {
55+
Console.WriteLine("Check Watcher Called");
56+
});
57+
check.Start();
58+
var idle = new IdleWatcher((ptr, stat) => {
59+
Console.WriteLine("Idle Watcher Called");
60+
});
61+
idle.Start();
5462
uv_run();
5563
}
5664
}

src/Libuv/CheckWatcher.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Libuv {
5+
public class CheckWatcher : Watcher {
6+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
7+
public delegate void uv_check_cb(IntPtr socket, int status);
8+
[DllImport("uvwrap")]
9+
internal static extern IntPtr create_check_watcher(IntPtr myself, uv_check_cb cb);
10+
[DllImport("uvwrap")]
11+
internal static extern int uv_check_init(IntPtr check);
12+
[DllImport("uvwrap")]
13+
internal static extern int manos_check_start(IntPtr check);
14+
[DllImport("uvwrap")]
15+
internal static extern int uv_check_stop(IntPtr check);
16+
private static uv_check_cb unmanaged_callback;
17+
private Action<CheckWatcher, int> callback;
18+
static CheckWatcher()
19+
{
20+
unmanaged_callback = StaticCallback;
21+
}
22+
public CheckWatcher(Action<CheckWatcher, int> callback)
23+
{
24+
watcher = create_check_watcher(GCHandle.ToIntPtr(gc_handle), unmanaged_callback);
25+
uv_check_init(this.watcher);
26+
this.callback = callback;
27+
}
28+
private static void StaticCallback(IntPtr watcher, int status)
29+
{
30+
var handle = GCHandle.FromIntPtr(watcher);
31+
var watcher_instance = (CheckWatcher)handle.Target;
32+
watcher_instance.callback(watcher_instance, status);
33+
}
34+
public void Start()
35+
{
36+
manos_check_start(this.watcher);
37+
}
38+
public void Stop()
39+
{
40+
uv_check_stop(this.watcher);
41+
}
42+
}
43+
}

src/Libuv/IdleWatcher.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Libuv {
5+
public class IdleWatcher : Watcher {
6+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
7+
public delegate void uv_idle_cb(IntPtr socket, int status);
8+
[DllImport("uvwrap")]
9+
internal static extern IntPtr create_idle_watcher(IntPtr myself, uv_idle_cb cb);
10+
[DllImport("uvwrap")]
11+
internal static extern int uv_idle_init(IntPtr idle);
12+
[DllImport("uvwrap")]
13+
internal static extern int manos_idle_start(IntPtr idle);
14+
[DllImport("uvwrap")]
15+
internal static extern int uv_idle_stop(IntPtr idle);
16+
private static uv_idle_cb unmanaged_callback;
17+
private Action<IdleWatcher, int> callback;
18+
static IdleWatcher()
19+
{
20+
unmanaged_callback = StaticCallback;
21+
}
22+
public IdleWatcher(Action<IdleWatcher, int> callback)
23+
{
24+
watcher = create_idle_watcher(GCHandle.ToIntPtr(gc_handle), unmanaged_callback);
25+
uv_idle_init(this.watcher);
26+
this.callback = callback;
27+
}
28+
private static void StaticCallback(IntPtr watcher, int status)
29+
{
30+
var handle = GCHandle.FromIntPtr(watcher);
31+
var watcher_instance = (IdleWatcher)handle.Target;
32+
watcher_instance.callback(watcher_instance, status);
33+
}
34+
public void Start()
35+
{
36+
manos_idle_start(this.watcher);
37+
}
38+
public void Stop()
39+
{
40+
uv_idle_stop(this.watcher);
41+
}
42+
}
43+
}

src/Libuv/Libuv.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
<Compile Include="TcpServer.cs" />
4646
<Compile Include="Watcher.cs" />
4747
<Compile Include="PrepareWatcher.cs" />
48+
<Compile Include="CheckWatcher.cs" />
49+
<Compile Include="IdleWatcher.cs" />
4850
</ItemGroup>
4951
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
5052
<Target Name="ListSources">

src/Libuv/PrepareWatcher.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,5 @@ public void Stop()
3939
{
4040
uv_prepare_stop(this.watcher);
4141
}
42-
~PrepareWatcher()
43-
{
44-
Cleanup();
45-
}
46-
private void Cleanup()
47-
{
48-
gc_handle.Free();
49-
destroy_watcher(this.watcher);
50-
}
51-
public override void Dispose()
52-
{
53-
Cleanup();
54-
GC.SuppressFinalize(this);
55-
56-
}
5742
}
5843
}

src/Libuv/Watcher.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@ public abstract class Watcher : IDisposable {
77
internal static extern void destroy_watcher(IntPtr watcher);
88
internal IntPtr watcher;
99
internal GCHandle gc_handle;
10-
public abstract void Dispose();
1110
internal Watcher()
1211
{
1312
gc_handle = GCHandle.Alloc(this);
1413
}
14+
~Watcher()
15+
{
16+
Cleanup();
17+
}
18+
private void Cleanup()
19+
{
20+
gc_handle.Free();
21+
destroy_watcher(this.watcher);
22+
}
23+
public void Dispose()
24+
{
25+
Cleanup();
26+
GC.SuppressFinalize(this);
27+
}
1528
}
1629
}

src/wrapper/uv_wrap.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,50 @@ typedef struct {
9898
void* cb;
9999
} manos_static_data_container;
100100
typedef void (*manos_static_cb)(void* handle, int status);
101-
static void prepare_cb(uv_prepare_t* prepare, int status)
101+
static void watcher_cb(uv_handle_t* watcher, int status)
102102
{
103-
manos_static_data_container* container = (manos_static_data_container*)prepare->data;
103+
manos_static_data_container* container = (manos_static_data_container*)watcher->data;
104104
manos_static_cb cb = container->cb;
105105
cb(container->data, status);
106106
}
107-
uv_prepare_t* create_prepare_watcher(void* data, void* cb)
107+
void addstruct(uv_handle_t* handle, void* data, void* cb)
108108
{
109-
uv_prepare_t* ret = malloc(sizeof(uv_prepare_t));
110109
manos_static_data_container* inter = malloc(sizeof(manos_static_data_container));
111110
inter->data = data;
112111
inter->cb = cb;
113-
ret->data = inter;
112+
handle->data = inter;
113+
}
114+
uv_prepare_t* create_prepare_watcher(void* data, void* cb)
115+
{
116+
uv_prepare_t* ret = malloc(sizeof(uv_prepare_t));
117+
addstruct((uv_handle_t*)ret, data, cb);
114118
return ret;
115119
}
116120
int manos_prepare_start(uv_prepare_t *ptr)
117121
{
118-
uv_prepare_start(ptr, prepare_cb);
122+
uv_prepare_start(ptr, watcher_cb);
123+
}
124+
uv_check_t* create_check_watcher(void* data, void* cb)
125+
{
126+
uv_check_t* ret = malloc(sizeof(uv_check_t));
127+
addstruct((uv_handle_t*)ret, data, cb);
128+
return ret;
129+
}
130+
int manos_check_start(uv_check_t *ptr)
131+
{
132+
uv_check_start(ptr, watcher_cb);
133+
}
134+
uv_idle_t* create_idle_watcher(void* data, void* cb)
135+
{
136+
uv_idle_t* ret = malloc(sizeof(uv_idle_t));
137+
addstruct((uv_handle_t*)ret, data, cb);
138+
return ret;
139+
}
140+
int manos_idle_start(uv_idle_t *ptr)
141+
{
142+
uv_idle_start(ptr, watcher_cb);
119143
}
120-
void destroy_watcher(uv_prepare_t* ptr)
144+
void destroy_watcher(uv_handle_t* ptr)
121145
{
122146
free(ptr->data);
123147
free(ptr);

0 commit comments

Comments
 (0)