Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit ad77599

Browse files
author
Sean Parker
authored
Native Event Tracing IO Wrappers (#1444)
* Add IOStream native wrapper * Add IOStorage native wrapper * Add changelog entry * Add sealed to IOStorage class * Remove GC SuppressFinalize call
1 parent 31251a5 commit ad77599

File tree

7 files changed

+207
-18
lines changed

7 files changed

+207
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
### Internal
2121

2222
- Added C# bindings for C Event Tracing API. [#1440](https://github.com/spatialos/gdk-for-unity/pull/1440)
23+
- Added native classes for IO operations in Event Tracing API. [#1444](https://github.com/spatialos/gdk-for-unity/pull/1444)
2324

2425
## `0.3.9` - 2020-07-24
2526

workers/unity/Packages/io.improbable.worker.sdk/CEventTrace.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public struct EventTracerParameters
278278
*/
279279
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
280280
EntryPoint = "Trace_Item_Create")]
281-
public static extern Item* ItemCreate(CIO.Storage storage, Item* item);
281+
public static extern Item* ItemCreate(CIO.StorageHandle storage, Item* item);
282282

283283
/**
284284
* Returns a pointer to a thread-local trace item.
@@ -320,7 +320,7 @@ public struct EventTracerParameters
320320
*/
321321
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
322322
EntryPoint = "Trace_SerializeItemToStream")]
323-
public static extern Int8 SerializeItemToStream(CIO.Stream stream, Item* item, Uint32 size);
323+
public static extern Int8 SerializeItemToStream(CIO.StreamHandle stream, Item* item, Uint32 size);
324324

325325
/**
326326
* Get the serialized size, in bytes, of the next serialized trace item to be read from the stream.
@@ -332,7 +332,7 @@ public struct EventTracerParameters
332332
*/
333333
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
334334
EntryPoint = "Trace_GetNextSerializedItemSize")]
335-
public static extern Uint32 GetNextSerializedItemSize(CIO.Stream stream);
335+
public static extern Uint32 GetNextSerializedItemSize(CIO.StreamHandle stream);
336336

337337
/**
338338
* Deserialize the next trace item from the stream.
@@ -356,7 +356,7 @@ public struct EventTracerParameters
356356
*/
357357
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
358358
EntryPoint = "Trace_DeserializeItemFromStream")]
359-
public static extern Int8 DeserializeItemFromStream(CIO.Stream stream, Item* item, Uint32 size);
359+
public static extern Int8 DeserializeItemFromStream(CIO.StreamHandle stream, Item* item, Uint32 size);
360360

361361
/**
362362
* Returns the last error which occurred during a trace API method call. Returns nullptr if no

workers/unity/Packages/io.improbable.worker.sdk/CIO.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Improbable.Worker.CInterop.Internal
1010
{
1111
internal unsafe class CIO
1212
{
13-
public class Storage : CptrHandle
13+
public class StorageHandle : CptrHandle
1414
{
1515
protected override bool ReleaseHandle()
1616
{
@@ -19,7 +19,7 @@ protected override bool ReleaseHandle()
1919
}
2020
}
2121

22-
public class Stream : CptrHandle
22+
public class StreamHandle : CptrHandle
2323
{
2424
protected override bool ReleaseHandle()
2525
{
@@ -45,7 +45,7 @@ public enum OpenMode
4545
*/
4646
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
4747
EntryPoint = "Io_Storage_Create")]
48-
public static extern Storage StorageCreate();
48+
public static extern StorageHandle StorageCreate();
4949

5050
/* Destroys the trace storage. */
5151
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
@@ -61,7 +61,7 @@ public enum OpenMode
6161
*/
6262
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
6363
EntryPoint = "Io_Storage_Clear")]
64-
public static extern void StorageClear(IntPtr storage);
64+
public static extern void StorageClear(StorageHandle storage);
6565

6666
/**
6767
* Creates an I/O stream implemented as a ring buffer.
@@ -77,7 +77,7 @@ public enum OpenMode
7777
*/
7878
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
7979
EntryPoint = "Io_CreateRingBufferStream")]
80-
public static extern Stream CreateRingBufferStream(Uint32 capacityBytes);
80+
public static extern StreamHandle CreateRingBufferStream(Uint32 capacityBytes);
8181

8282
/**
8383
* Creates an I/O stream implemented as a read/write file.
@@ -94,7 +94,7 @@ public enum OpenMode
9494
*/
9595
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
9696
EntryPoint = "Io_CreateFileStream")]
97-
public static extern Stream CreateFileStream(Char* filename, OpenMode openMode);
97+
public static extern StreamHandle CreateFileStream(Char* filename, OpenMode openMode);
9898

9999
/* Destroys the I/O stream. */
100100
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
@@ -111,7 +111,7 @@ public enum OpenMode
111111
*/
112112
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
113113
EntryPoint = "Io_Stream_Write")]
114-
public static extern Int64 StreamWrite(Stream stream, Uint8* bytes, Uint32 length);
114+
public static extern Int64 StreamWrite(StreamHandle stream, Uint8* bytes, Uint32 length);
115115

116116
/**
117117
* Gets the remaining write capacity in bytes.
@@ -121,7 +121,7 @@ public enum OpenMode
121121
*/
122122
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
123123
EntryPoint = "Io_Stream_GetRemainingWriteCapacityBytes")]
124-
public static extern Uint32 StreamGetRemainingWriteCapacityBytes(Stream stream);
124+
public static extern Uint32 StreamGetRemainingWriteCapacityBytes(StreamHandle stream);
125125

126126
/**
127127
* Reads as much of the stream's data as possible into the given buffer.
@@ -133,7 +133,7 @@ public enum OpenMode
133133
*/
134134
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
135135
EntryPoint = "Io_Stream_Read")]
136-
public static extern Uint64 StreamRead(Stream stream, Uint8* bytes, Uint32 length);
136+
public static extern Int64 StreamRead(StreamHandle stream, Uint8* bytes, Uint32 length);
137137

138138
/**
139139
* Reads as much of the stream's data as possible into the given buffer without advancing the read
@@ -142,11 +142,11 @@ public enum OpenMode
142142
* Returns the actual number of bytes read. This may be less than the given length iff the stream
143143
* has less data than the requested amount.
144144
*
145-
* Returns -1 on error. Call StreamGetLastError() to get the associated error message.
145+
* Returns -1 on error. Call StreamGetLastError to get the associated error message.
146146
*/
147147
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
148148
EntryPoint = "Io_Stream_Peek")]
149-
public static extern Int64 StreamPeek(Stream stream, Uint8* bytes, Uint32 length);
149+
public static extern Int64 StreamPeek(StreamHandle stream, Uint8* bytes, Uint32 length);
150150

151151
/**
152152
* Extracts the given number of bytes from the stream and discards them.
@@ -155,18 +155,18 @@ public enum OpenMode
155155
* has advanced. This may be less than the given length iff the stream has less data than the
156156
* requested amount.
157157
*
158-
* Returns -1 on error. Call StreamGetLastError() to get the associated error message.
158+
* Returns -1 on error. Call StreamGetLastError to get the associated error message.
159159
*/
160160
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
161161
EntryPoint = "Io_Stream_Ignore")]
162-
public static extern Int64 StreamIgnore(Stream stream, Uint32 length);
162+
public static extern Int64 StreamIgnore(StreamHandle stream, Uint32 length);
163163

164164
/**
165165
* Returns the last error which occurred during an API call on this stream. Returns nullptr if no
166166
* such error has occurred.
167167
*/
168168
[DllImport(Constants.WorkerLibrary, CallingConvention = CallingConvention.Cdecl,
169169
EntryPoint = "Io_Stream_GetLastError")]
170-
public static extern Char* StreamGetLastError(Stream stream);
170+
public static extern Char* StreamGetLastError(StreamHandle stream);
171171
}
172172
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using Improbable.Worker.CInterop.Internal;
3+
4+
namespace Improbable.Worker.CInterop
5+
{
6+
public sealed class IOStorage : IDisposable
7+
{
8+
private readonly CIO.StorageHandle storage;
9+
10+
public IOStorage()
11+
{
12+
storage = CIO.StorageCreate();
13+
}
14+
15+
/// <inheritdoc cref="IDisposable"/>
16+
public void Dispose()
17+
{
18+
storage.Dispose();
19+
}
20+
21+
public void Clear()
22+
{
23+
CIO.StorageClear(storage);
24+
}
25+
}
26+
}

workers/unity/Packages/io.improbable.worker.sdk/IOStorage.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System;
2+
using System.IO;
3+
using Improbable.Worker.CInterop.Internal;
4+
5+
namespace Improbable.Worker.CInterop
6+
{
7+
public enum OpenMode
8+
{
9+
/* Opens the stream in the default mode. */
10+
OpenModeDefault = 0x00,
11+
}
12+
13+
public sealed unsafe class IOStream : IDisposable
14+
{
15+
private readonly CIO.StreamHandle stream;
16+
17+
private IOStream(CIO.StreamHandle stream)
18+
{
19+
this.stream = stream;
20+
}
21+
22+
/// <inheritdoc cref="IDisposable"/>
23+
public void Dispose()
24+
{
25+
stream.Dispose();
26+
}
27+
28+
public static IOStream CreateRingBufferStream(uint capacity)
29+
{
30+
return new IOStream(CIO.CreateRingBufferStream(capacity));
31+
}
32+
33+
public static IOStream CreateFileStream(string fileName, OpenMode openMode)
34+
{
35+
fixed (byte* fileNameBytes = ApiInterop.ToUtf8Cstr(fileName))
36+
{
37+
return new IOStream(CIO.CreateFileStream(fileNameBytes, (CIO.OpenMode) openMode));
38+
}
39+
}
40+
41+
public long Write(byte[] data)
42+
{
43+
ThrowIfStreamClosed();
44+
45+
var remainingCapacity = CIO.StreamGetRemainingWriteCapacityBytes(stream);
46+
if (remainingCapacity < data.Length)
47+
{
48+
throw new NotSupportedException("Not enough stream capacity to write data.");
49+
}
50+
51+
var bytesWritten = 0L;
52+
fixed (byte* dataToWrite = data)
53+
{
54+
bytesWritten = CIO.StreamWrite(stream, dataToWrite, 1);
55+
}
56+
57+
if (bytesWritten != -1)
58+
{
59+
return bytesWritten;
60+
}
61+
62+
var rawError = CIO.StreamGetLastError(stream);
63+
throw new IOException(ApiInterop.FromUtf8Cstr(rawError));
64+
}
65+
66+
public long Read(uint bytesToRead, out byte[] streamData)
67+
{
68+
ThrowIfStreamClosed();
69+
70+
streamData = new byte[bytesToRead];
71+
72+
var bytesRead = 0L;
73+
fixed (byte* streamDataPointer = streamData)
74+
{
75+
bytesRead = CIO.StreamRead(stream, streamDataPointer, bytesToRead);
76+
}
77+
78+
if (bytesRead != -1)
79+
{
80+
return bytesRead;
81+
}
82+
83+
var rawError = CIO.StreamGetLastError(stream);
84+
throw new IOException(ApiInterop.FromUtf8Cstr(rawError));
85+
}
86+
87+
public long Read(byte[] streamData)
88+
{
89+
ThrowIfStreamClosed();
90+
91+
var bytesToRead = (uint) streamData.Length;
92+
var bytesRead = 0L;
93+
fixed (byte* streamDataPointer = streamData)
94+
{
95+
bytesRead = CIO.StreamRead(stream, streamDataPointer, bytesToRead);
96+
}
97+
98+
if (bytesRead != -1)
99+
{
100+
return bytesRead;
101+
}
102+
103+
var rawError = CIO.StreamGetLastError(stream);
104+
throw new IOException(ApiInterop.FromUtf8Cstr(rawError));
105+
}
106+
107+
public long Peek(uint bytesToPeek, out byte[] streamData)
108+
{
109+
ThrowIfStreamClosed();
110+
111+
streamData = new byte[bytesToPeek];
112+
113+
var bytesPeeked = 0L;
114+
fixed (byte* streamDataPointer = streamData)
115+
{
116+
bytesPeeked = CIO.StreamPeek(stream, streamDataPointer, bytesToPeek);
117+
}
118+
119+
if (bytesPeeked != -1)
120+
{
121+
return bytesPeeked;
122+
}
123+
124+
var rawError = CIO.StreamGetLastError(stream);
125+
throw new IOException(ApiInterop.FromUtf8Cstr(rawError));
126+
}
127+
128+
public long Ignore(uint bytesToIgnore)
129+
{
130+
ThrowIfStreamClosed();
131+
132+
var bytesIgnored = CIO.StreamIgnore(stream, bytesToIgnore);
133+
134+
if (bytesIgnored != -1)
135+
{
136+
return bytesIgnored;
137+
}
138+
139+
var rawError = CIO.StreamGetLastError(stream);
140+
throw new IOException(ApiInterop.FromUtf8Cstr(rawError));
141+
}
142+
143+
public uint GetRemainingCapacity()
144+
{
145+
return CIO.StreamGetRemainingWriteCapacityBytes(stream);
146+
}
147+
148+
private void ThrowIfStreamClosed()
149+
{
150+
if (stream.IsClosed)
151+
{
152+
throw new ObjectDisposedException("Cannot access a disposed object.");
153+
}
154+
}
155+
}
156+
}

workers/unity/Packages/io.improbable.worker.sdk/IOStream.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)