Skip to content

Commit

Permalink
Feature: Lock Buffer and Execute Function
Browse files Browse the repository at this point in the history
  • Loading branch information
Sewer56 committed Aug 3, 2019
1 parent 0439812 commit 35b4984
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 31 deletions.
82 changes: 53 additions & 29 deletions Source/Reloaded.Memory.Buffers/MemoryBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,27 @@ Core Functions
--------------
*/

/// <summary>
/// Locks a buffer from use by others and executes a given function.
/// </summary>
/// <param name="func">The function to execute while preventing others' access to the buffer.</param>
public T ExecuteWithLock<T>(Func<T> func)
{
try
{
_bufferAddMutex.WaitOne();
var result = func();
_bufferAddMutex.ReleaseMutex();

return result;
}
catch (Exception ex)
{
_bufferAddMutex.ReleaseMutex();
throw;
}
}

/// <summary>
/// Writes your own memory bytes into process' memory and gives you the address
/// for the memory location of the written bytes.
Expand All @@ -115,24 +136,25 @@ Core Functions
/// <returns>Pointer to the passed in bytes written to memory. Null pointer, if it cannot fit into the buffer.</returns>
public IntPtr Add(byte[] bytesToWrite, int alignment = 4)
{
_bufferAddMutex.WaitOne();
var bufferProperties = Properties;
return ExecuteWithLock(() =>
{
var bufferProperties = Properties;
// Re-align the buffer before write operation.
bufferProperties.SetAlignment(alignment);
// Re-align the buffer before write operation.
bufferProperties.SetAlignment(alignment);
// Check if item can fit in buffer and buffer address is valid.
if (Properties.Remaining < bytesToWrite.Length) // Inlined CanItemFit to prevent reading Properties from memory again.
return IntPtr.Zero;
// Check if item can fit in buffer and buffer address is valid.
if (Properties.Remaining < bytesToWrite.Length) // Inlined CanItemFit to prevent reading Properties from memory again.
return IntPtr.Zero;
// Append the item to the buffer.
IntPtr appendAddress = bufferProperties.WritePointer;
MemorySource.WriteRaw(appendAddress, bytesToWrite);
bufferProperties.Offset += bytesToWrite.Length;
Properties = bufferProperties;
// Append the item to the buffer.
IntPtr appendAddress = bufferProperties.WritePointer;
MemorySource.WriteRaw(appendAddress, bytesToWrite);
bufferProperties.Offset += bytesToWrite.Length;
Properties = bufferProperties;
_bufferAddMutex.ReleaseMutex();
return appendAddress;
return appendAddress;
});
}

/// <summary>
Expand All @@ -145,26 +167,28 @@ public IntPtr Add(byte[] bytesToWrite, int alignment = 4)
/// <returns>Pointer to the newly written structure in memory. Null pointer, if it cannot fit into the buffer.</returns>
public IntPtr Add<TStructure>(ref TStructure bytesToWrite, bool marshalElement = false, int alignment = 4)
{
_bufferAddMutex.WaitOne();
var bufferProperties = Properties;
var bytesToWriteByVal = bytesToWrite;
return ExecuteWithLock(() =>
{
var bufferProperties = Properties;
int structLength = Struct.GetSize<TStructure>(marshalElement);
int structLength = Struct.GetSize<TStructure>(marshalElement);
// Re-align the buffer before write operation.
bufferProperties.SetAlignment(alignment);
// Re-align the buffer before write operation.
bufferProperties.SetAlignment(alignment);
// Check if item can fit in buffer and buffer address is valid.
if (Properties.Remaining < structLength) // Inlined CanItemFit to prevent reading Properties from memory again.
return IntPtr.Zero;
// Check if item can fit in buffer and buffer address is valid.
if (Properties.Remaining < structLength) // Inlined CanItemFit to prevent reading Properties from memory again.
return IntPtr.Zero;
// Append the item to the buffer.
IntPtr appendAddress = bufferProperties.WritePointer;
MemorySource.Write(appendAddress, ref bytesToWrite, marshalElement);
bufferProperties.Offset += structLength;
Properties = bufferProperties;
// Append the item to the buffer.
IntPtr appendAddress = bufferProperties.WritePointer;
MemorySource.Write(appendAddress, ref bytesToWriteByVal, marshalElement);
bufferProperties.Offset += structLength;
Properties = bufferProperties;
_bufferAddMutex.ReleaseMutex();
return appendAddress;
return appendAddress;
});
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions Source/Reloaded.Memory.Buffers/Reloaded.Memory.Buffers.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>
Expand All @@ -15,7 +15,7 @@
<RepositoryUrl>https://github.com/Reloaded-Project/Reloaded.Memory.Buffers</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Description>An implementation of efficient, shared, concurrent and permanent storage of objects in unmanaged memory in static, non-changing locations that last the lifetime of a given process.</Description>
<Version>1.2.0</Version>
<Version>1.3.0</Version>
<Authors>Sewer56</Authors>
<Company></Company>
<Product>Project Reloaded</Product>
Expand Down

0 comments on commit 35b4984

Please sign in to comment.