mirror of https://github.com/buggins/dlangide.git
blocking queue
This commit is contained in:
parent
87f12a9435
commit
46256ca650
|
@ -7,20 +7,102 @@ class BlockingQueue(T) {
|
||||||
|
|
||||||
private Mutex _mutex;
|
private Mutex _mutex;
|
||||||
private Condition _condition;
|
private Condition _condition;
|
||||||
|
private T[] _buffer;
|
||||||
|
private int _readPos;
|
||||||
|
private int _writePos;
|
||||||
|
|
||||||
this() {
|
this() {
|
||||||
_mutex = new Mutex();
|
_mutex = new Mutex();
|
||||||
_condition = new Condition(_mutex);
|
_condition = new Condition(_mutex);
|
||||||
|
_readPos = 0;
|
||||||
|
_writePos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
if (_condition) {
|
||||||
|
destroy(_condition);
|
||||||
|
_condition = null;
|
||||||
|
}
|
||||||
|
if (_mutex) {
|
||||||
|
destroy(_mutex);
|
||||||
|
_mutex = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~this() {
|
~this() {
|
||||||
// TODO: destroy mutex?
|
// TODO: destroy mutex?
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void move() {
|
||||||
|
if (_readPos > 1024 && _readPos > _buffer.length * 3 / 4) {
|
||||||
|
// move buffer data
|
||||||
|
for (int i = 0; _readPos + i < _writePos; i++)
|
||||||
|
_buffer[i] = _buffer[_readPos + i];
|
||||||
|
_writePos -= _readPos;
|
||||||
|
_readPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(ref T item) {
|
||||||
|
if (_writePos >= _buffer.length) {
|
||||||
|
move();
|
||||||
|
_buffer.length = _buffer.length == 0 ? 64 : _buffer.length * 2;
|
||||||
|
}
|
||||||
|
_buffer[_writePos++] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void put(T item) {
|
void put(T item) {
|
||||||
|
synchronized(_mutex) {
|
||||||
|
append(item);
|
||||||
|
_condition.notifyAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void put(T[] items) {
|
||||||
|
synchronized(_mutex) {
|
||||||
|
foreach(ref item; items) {
|
||||||
|
append(item);
|
||||||
|
}
|
||||||
|
append(item);
|
||||||
|
_condition.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool get(ref T value, int timeoutMillis) {
|
bool get(ref T value, int timeoutMillis) {
|
||||||
|
synchronized(_mutex) {
|
||||||
|
if (_readPos < _writePos) {
|
||||||
|
value = _buffer[_readPos++];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (timeoutMillis <= 0)
|
||||||
|
_condition.wait(); // no timeout
|
||||||
|
else if (!_condition.wait(dur!msecs(timeoutMillis)))
|
||||||
|
return false; // timeout
|
||||||
|
if (_readPos < _writePos) {
|
||||||
|
value = _buffer[_readPos++];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getAll(ref T[] values, int timeoutMillis) {
|
||||||
|
synchronized(_mutex) {
|
||||||
|
values.length = 0;
|
||||||
|
while (_readPos < _writePos)
|
||||||
|
values ~= _buffer[_readPos++];
|
||||||
|
if (values.length > 0)
|
||||||
|
return true;
|
||||||
|
if (timeoutMillis <= 0)
|
||||||
|
_condition.wait(); // no timeout
|
||||||
|
else if (!_condition.wait(dur!msecs(timeoutMillis)))
|
||||||
|
return false; // timeout
|
||||||
|
while (_readPos < _writePos)
|
||||||
|
values ~= _buffer[_readPos++];
|
||||||
|
if (values.length > 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue