[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Sc-devel] [bug] possible race condition in server betweenSC_AudioDriver::RunThread()and ProcessOSCPacket()



Thanks James

#4 use a separate FIFO for sending OSC packets to the RT Engine. This would mean zero interference with the scheduling of the NRT thread, and wouldn't add much additional code (although it would lead to allocating another FIFO
buffer)...

4 is better in the long run.

Ok, I'll go with 4. I've made the patch below (not comitted). It adds a new mOscPacketsToEngine FIFO to SC_AudioDriver and the SendOscPacketMsgToEngine() member for enqueuing messages on it.

ProcessOSCPacket() has been modified to call SendOscPacketMsgToEngine.

Each AudioDriver's buffer processing routine has an added call to mOscPacketsToEngine.Perform();

I thought a little bit about whether to do:

mToEngine.Perform();
mOscPacketsToEngine.Perform();

or

mOscPacketsToEngine.Perform();
mToEngine.Perform();

Not sure there's a significant difference.

Shall I commit it?

In general I can't tell if there's any logic to the placement of the queues in AudioDriver but mDriverLock in mWorld rather than in AudioDriver.. is it just a legacy thing?

Ross.




Index: Headers/server/SC_CoreAudio.h
===================================================================
--- Headers/server/SC_CoreAudio.h       (revision 6865)
+++ Headers/server/SC_CoreAudio.h       (working copy)
@@ -95,6 +95,7 @@
       // Common members
uint32 mHardwareBufferSize; // bufferSize returned by kAudioDevicePropertyBufferSize
       EngineFifo mFromEngine, mToEngine;
+       EngineFifo mOscPacketsToEngine;
       SC_SyncCondition mAudioSync;
       pthread_t mThread;
       bool mRunThreadFlag;
@@ -147,9 +148,10 @@
               mPreferredSampleRate = inRate;
       }

-       bool SendMsgToEngine(FifoMsg& inMsg);
+ bool SendMsgToEngine(FifoMsg& inMsg); // called by NRT thread
       bool SendMsgFromEngine(FifoMsg& inMsg);
-
+ bool SendOscPacketMsgToEngine(FifoMsg& inMsg); // called by OSC socket listener threads, protected by mWorld->mDriverLock
+
       void AddEvent(SC_ScheduledEvent& event) { mScheduler.Add(event); }

       double GetAvgCPU() const { return mAvgCPU; }


Index: Source/server/SC_CoreAudio.cpp
===================================================================
--- Source/server/SC_CoreAudio.cpp      (revision 6865)
+++ Source/server/SC_CoreAudio.cpp      (working copy)
@@ -191,7 +191,7 @@
inPacket->mIsBundle = gIsBundle.checkIsBundle((int32*)inPacket->mData);
               FifoMsg fifoMsg;
fifoMsg.Set(inWorld, Perform_ToEngine_Msg, FreeOSCPacket, (void*)inPacket);
-               result = driver->SendMsgToEngine(fifoMsg);
+               result = driver->SendOscPacketMsgToEngine(fifoMsg);
       inWorld->mDriverLock->Unlock();
       return result;
}
@@ -389,6 +389,12 @@
       return mToEngine.Write(inMsg);
}

+bool SC_AudioDriver::SendOscPacketMsgToEngine(FifoMsg& inMsg)
+{
+       mOscPacketsToEngine.Free();
+       return mOscPacketsToEngine.Write(inMsg);
+}
+
void SC_ScheduledEvent::Perform()
{
       PerformOSCBundle(mWorld, mPacket);
@@ -910,6 +916,7 @@
scprintf("oscTime %.9f %.9f\n", oscTime*kOSCtoSecs, CoreAudioHostTimeToOSC(AudioGetCurrentHostTime())*kOSCtoSecs);
               }*/
               mToEngine.Perform();
+               mOscPacketsToEngine.Perform();

               int bufFrames = world->mBufLength;
               int numBufs = numSamplesPerCallback / bufFrames;
@@ -1565,6 +1572,7 @@

               mFromEngine.Free();
               mToEngine.Perform();
+               mOscPacketsToEngine.Perform();

               int numInputs = mInputChannelCount;
               int numOutputs = mOutputChannelCount;
@@ -1803,6 +1811,7 @@

               mFromEngine.Free();
               mToEngine.Perform();
+               mOscPacketsToEngine.Perform();

               int numInputs = mInputChannelCount;
               int numOutputs = mOutputChannelCount;