additional edge-case thread safety for RNG buffer filling

This commit is contained in:
Mark Sturgill 2014-02-09 13:02:20 -07:00
parent a5b7e6c78c
commit cfdd943142

View file

@ -115,8 +115,9 @@ namespace Server {
private int _Index = 0;
private object _sync = new object();
private object _syncB = new object();
private object _sync = new object();
private ManualResetEvent _filled = new ManualResetEvent(false);
public CSPRandom() {
_CSP.GetBytes(_Working);
@ -125,21 +126,25 @@ namespace Server {
private void CheckSwap(int c) {
if (_Index + c < BUFFER_SIZE)
return;
return;
_filled.WaitOne();
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
_filled.Reset();
lock (_syncB) {
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
}
ThreadPool.QueueUserWorkItem(new WaitCallback(Fill));
}
private void Fill(object o) {
lock (_syncB)
lock (_CSP)
_CSP.GetBytes(_Buffer);
lock (_CSP)
_CSP.GetBytes(_Buffer);
_filled.Set();
}
private void _GetBytes(byte[] b) {
@ -227,8 +232,9 @@ namespace Server {
private int _Index = 0;
private object _sync = new object();
private object _syncB = new object();
private object _sync = new object();
private ManualResetEvent _filled = new ManualResetEvent(false);
public RDRand32() {
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Working);
@ -244,18 +250,21 @@ namespace Server {
if (_Index + c < BUFFER_SIZE)
return;
lock (_syncB) {
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
}
_filled.WaitOne();
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
_filled.Reset();
ThreadPool.QueueUserWorkItem(new WaitCallback(Fill));
}
private void Fill(object o) {
lock (_syncB)
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
_filled.Set();
}
private void _GetBytes(byte[] b) {
@ -342,8 +351,9 @@ namespace Server {
private int _Index = 0;
private object _sync = new object();
private object _syncB = new object();
private object _sync = new object();
private ManualResetEvent _filled = new ManualResetEvent(false);
public RDRand64() {
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Working);
@ -359,18 +369,21 @@ namespace Server {
if (_Index + c < BUFFER_SIZE)
return;
lock (_syncB) {
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
}
_filled.WaitOne();
byte[] b = _Working;
_Working = _Buffer;
_Buffer = b;
_Index = 0;
_filled.Reset();
ThreadPool.QueueUserWorkItem(new WaitCallback(Fill));
}
private void Fill(object o) {
lock (_syncB)
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
_filled.Set();
}
private void _GetBytes(byte[] b) {