-
Notifications
You must be signed in to change notification settings - Fork 0
/
BufferManager.cs
57 lines (51 loc) · 2.05 KB
/
BufferManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System.Net.Sockets;
namespace SocketHelper;
// modified from: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socketasynceventargs.setbuffer?view=net-8.0#system-net-sockets-socketasynceventargs-setbuffer(system-byte()-system-int32-system-int32)
// This class creates a single large buffer which can be divided up
// and assigned to SocketAsyncEventArgs objects for use with each
// socket I/O operation.
// This enables bufffers to be easily reused and guards against
// fragmenting heap memory.
//
// The operations exposed on the BufferManager class are not thread safe.
class BufferManager {
int m_numBytes; // the total number of bytes controlled by the buffer pool
byte[] m_buffer; // the underlying byte array maintained by the Buffer Manager
Stack<int> m_freeIndexPool; //
int m_currentIndex;
int m_bufferSize;
public BufferManager(int totalBytes, int bufferSize) {
m_numBytes = totalBytes;
m_currentIndex = 0;
m_bufferSize = bufferSize;
m_freeIndexPool = new Stack<int>();
}
// Allocates buffer space used by the buffer pool
public void InitBuffer() {
// create one big large buffer and divide that
// out to each SocketAsyncEventArg object
m_buffer = new byte[m_numBytes];
}
// Assigns a buffer from the buffer pool to the
// specified SocketAsyncEventArgs object
//
// <returns>true if the buffer was successfully set, else false</returns>
public bool SetBuffer(SocketAsyncEventArgs args) {
if (m_freeIndexPool.Count > 0) {
args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);
} else {
if ((m_numBytes - m_bufferSize) < m_currentIndex) {
return false;
}
args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);
m_currentIndex += m_bufferSize;
}
return true;
}
// Removes the buffer from a SocketAsyncEventArg object.
// This frees the buffer back to the buffer pool
public void FreeBuffer(SocketAsyncEventArgs args) {
m_freeIndexPool.Push(args.Offset);
args.SetBuffer(null, 0, 0);
}
}