Skip to content

Commit 88e53b9

Browse files
committed
2 parents 41f80e6 + 493e236 commit 88e53b9

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

RtMidi.cpp

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -344,28 +344,41 @@ double MidiInApi :: getMessage( std::vector<unsigned char> *message )
344344
return 0.0;
345345
}
346346

347-
if ( inputData_.queue.size == 0 ) return 0.0;
348-
349347
double timeStamp;
350348
if (!inputData_.queue.pop(message, &timeStamp))
351349
return 0.0;
352350

353351
return timeStamp;
354352
}
355353

356-
bool MidiInApi::MidiQueue::push(const MidiInApi::MidiMessage& msg)
354+
unsigned int MidiInApi::MidiQueue::size(unsigned int *__back,
355+
unsigned int *__front)
357356
{
358-
// As long as we haven't reached our queue size limit, push the message.
359-
unsigned int _back = back;
360-
unsigned int _front = front;
361-
unsigned int size;
362-
357+
// Access back/front members exactly once and make stack copies for
358+
// size calculation
359+
unsigned int _back = back, _front = front, _size;
363360
if (_back >= _front)
364-
size = _back - _front;
361+
_size = _back - _front;
365362
else
366-
size = ringSize - _front + _back;
363+
_size = ringSize - _front + _back;
364+
365+
// Return copies of back/front so no new and unsynchronized accesses
366+
// to member variables are needed.
367+
if (__back) *__back = _back;
368+
if (__front) *__front = _front;
369+
return _size;
370+
}
371+
372+
// As long as we haven't reached our queue size limit, push the message.
373+
bool MidiInApi::MidiQueue::push(const MidiInApi::MidiMessage& msg)
374+
{
375+
// Local stack copies of front/back
376+
unsigned int _back, _front, _size;
377+
378+
// Get back/front indexes exactly once and calculate current size
379+
_size = size(&_back, &_front);
367380

368-
if ( size < ringSize-1 )
381+
if ( _size < ringSize-1 )
369382
{
370383
ring[_back] = msg;
371384
back = (back+1)%ringSize;
@@ -377,21 +390,20 @@ bool MidiInApi::MidiQueue::push(const MidiInApi::MidiMessage& msg)
377390

378391
bool MidiInApi::MidiQueue::pop(std::vector<unsigned char> *msg, double* timeStamp)
379392
{
380-
unsigned int _back = back;
381-
unsigned int _front = front;
382-
unsigned int size;
393+
// Local stack copies of front/back
394+
unsigned int _back, _front, _size;
383395

384-
if (_back >= _front)
385-
size = _back - _front;
386-
else
387-
size = ringSize - _front + _back;
396+
// Get back/front indexes exactly once and calculate current size
397+
_size = size(&_back, &_front);
388398

389-
if (size == 0)
399+
if (_size == 0)
390400
return false;
391401

392402
// Copy queued message to the vector pointer argument and then "pop" it.
393403
msg->assign( ring[_front].bytes.begin(), ring[_front].bytes.end() );
394404
*timeStamp = ring[_front].timeStamp;
405+
406+
// Update front
395407
front = (front+1)%ringSize;
396408
return true;
397409
}

RtMidi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,15 +516,16 @@ class MidiInApi : public MidiApi
516516
struct MidiQueue {
517517
unsigned int front;
518518
unsigned int back;
519-
unsigned int size;
520519
unsigned int ringSize;
521520
MidiMessage *ring;
522521

523522
// Default constructor.
524523
MidiQueue()
525-
:front(0), back(0), size(0), ringSize(0), ring(0) {}
524+
:front(0), back(0), ringSize(0), ring(0) {}
526525
bool push(const MidiMessage&);
527526
bool pop(std::vector<unsigned char>*, double*);
527+
unsigned int size(unsigned int *back=0,
528+
unsigned int *front=0);
528529
};
529530

530531
// The RtMidiInData structure is used to pass private class data to

0 commit comments

Comments
 (0)