@@ -344,28 +344,41 @@ double MidiInApi :: getMessage( std::vector<unsigned char> *message )
344
344
return 0.0 ;
345
345
}
346
346
347
- if ( inputData_.queue .size == 0 ) return 0.0 ;
348
-
349
347
double timeStamp;
350
348
if (!inputData_.queue .pop (message, &timeStamp))
351
349
return 0.0 ;
352
350
353
351
return timeStamp;
354
352
}
355
353
356
- bool MidiInApi::MidiQueue::push (const MidiInApi::MidiMessage& msg)
354
+ unsigned int MidiInApi::MidiQueue::size (unsigned int *__back,
355
+ unsigned int *__front)
357
356
{
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;
363
360
if (_back >= _front)
364
- size = _back - _front;
361
+ _size = _back - _front;
365
362
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);
367
380
368
- if ( size < ringSize-1 )
381
+ if ( _size < ringSize-1 )
369
382
{
370
383
ring[_back] = msg;
371
384
back = (back+1 )%ringSize;
@@ -377,21 +390,20 @@ bool MidiInApi::MidiQueue::push(const MidiInApi::MidiMessage& msg)
377
390
378
391
bool MidiInApi::MidiQueue::pop (std::vector<unsigned char > *msg, double * timeStamp)
379
392
{
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;
383
395
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);
388
398
389
- if (size == 0 )
399
+ if (_size == 0 )
390
400
return false ;
391
401
392
402
// Copy queued message to the vector pointer argument and then "pop" it.
393
403
msg->assign ( ring[_front].bytes .begin (), ring[_front].bytes .end () );
394
404
*timeStamp = ring[_front].timeStamp ;
405
+
406
+ // Update front
395
407
front = (front+1 )%ringSize;
396
408
return true ;
397
409
}
0 commit comments