Browse Source

Improve error management in JackNetDriver.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4249 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 14 years ago
parent
commit
e03d1ddd44
6 changed files with 86 additions and 70 deletions
  1. +1
    -0
      ChangeLog
  2. +15
    -6
      common/JackAudioDriver.cpp
  3. +6
    -5
      common/JackNetDriver.cpp
  4. +40
    -40
      common/JackNetInterface.cpp
  5. +2
    -0
      common/JackNetTool.cpp
  6. +22
    -19
      common/JackWaitThreadedDriver.h

+ 1
- 0
ChangeLog View File

@@ -40,6 +40,7 @@ Valerio Pilo
* Cleanup JackThreadedDriver::Stop. * Cleanup JackThreadedDriver::Stop.
* Correct JackNetOneDriver::Close. * Correct JackNetOneDriver::Close.
* Correction in jackdmp.cpp: notify_server_stop should be done after server destruction. * Correction in jackdmp.cpp: notify_server_stop should be done after server destruction.
* Improve error management in JackNetDriver.


2011-03-30 Stephane Letz <letz@grame.fr> 2011-03-30 Stephane Letz <letz@grame.fr>




+ 15
- 6
common/JackAudioDriver.cpp View File

@@ -82,6 +82,9 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size,
fCaptureChannels = inchannels; fCaptureChannels = inchannels;
fPlaybackChannels = outchannels; fPlaybackChannels = outchannels;
fWithMonitorPorts = monitor; fWithMonitorPorts = monitor;
memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
} }


@@ -98,6 +101,9 @@ int JackAudioDriver::Open(bool capturing,
fCaptureChannels = inchannels; fCaptureChannels = inchannels;
fPlaybackChannels = outchannels; fPlaybackChannels = outchannels;
fWithMonitorPorts = monitor; fWithMonitorPorts = monitor;
memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
} }


@@ -389,20 +395,23 @@ void JackAudioDriver::WaitUntilNextCycle()


jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index)
{ {
assert(fCapturePortList[port_index]);
return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize);
return fCapturePortList[port_index]
? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize)
: NULL;
} }


jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index)
{ {
assert(fPlaybackPortList[port_index]);
return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize);
return fPlaybackPortList[port_index]
? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize)
: NULL;
} }


jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index)
{ {
assert(fPlaybackPortList[port_index]);
return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize);
return fPlaybackPortList[port_index]
? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize)
: NULL;
} }


int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)


+ 6
- 5
common/JackNetDriver.cpp View File

@@ -142,8 +142,10 @@ namespace Jack
( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );


//init network //init network
if ( !JackNetSlaveInterface::Init() )
if (!JackNetSlaveInterface::Init()) {
jack_error("Starting network fails...");
return false; return false;
}


//set global parameters //set global parameters
SetParams(); SetParams();
@@ -163,14 +165,13 @@ namespace Jack
} }


//register jack ports //register jack ports
if ( AllocPorts() != 0 )
{
jack_error ( "Can't allocate ports." );
if (AllocPorts() != 0) {
jack_error("Can't allocate ports.");
return false; return false;
} }


//init done, display parameters //init done, display parameters
SessionParamsDisplay ( &fParams );
SessionParamsDisplay(&fParams);


//monitor //monitor
#ifdef JACK_MONITOR #ifdef JACK_MONITOR


+ 40
- 40
common/JackNetInterface.cpp View File

@@ -24,9 +24,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


using namespace std; using namespace std;


/*
TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
probably also use BUFFER_SIZE_MAX in everything related to MIDI events
/*
TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
probably also use BUFFER_SIZE_MAX in everything related to MIDI events
handling (see MidiBufferInit in JackMidiPort.cpp) handling (see MidiBufferInit in JackMidiPort.cpp)
*/ */


@@ -212,7 +212,7 @@ namespace Jack
//timeout on receive (for init) //timeout on receive (for init)
if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 ) if ( fSocket.SetTimeOut ( MASTER_INIT_TIMEOUT ) < 0 )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
//connect //connect
if ( fSocket.Connect() == SOCKET_ERROR ) { if ( fSocket.Connect() == SOCKET_ERROR ) {
jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't connect : %s", StrError ( NET_ERROR_CODE ) );
@@ -230,17 +230,17 @@ namespace Jack
memset(&net_params, 0, sizeof ( session_params_t )); memset(&net_params, 0, sizeof ( session_params_t ));
SetPacketType ( &fParams, SLAVE_SETUP ); SetPacketType ( &fParams, SLAVE_SETUP );
SessionParamsHToN(&fParams, &net_params); SessionParamsHToN(&fParams, &net_params);
if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR )
jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) ); jack_error ( "Error in send : ", StrError ( NET_ERROR_CODE ) );
memset(&net_params, 0, sizeof ( session_params_t )); memset(&net_params, 0, sizeof ( session_params_t ));
if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) if ( ( ( rx_bytes = fSocket.Recv ( &net_params, sizeof ( session_params_t ), 0 ) ) == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
{ {
jack_error ( "Problem with network." ); jack_error ( "Problem with network." );
return false; return false;
} }
SessionParamsNToH(&net_params, &host_params); SessionParamsNToH(&net_params, &host_params);
} }
while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) ); while ( ( GetPacketType ( &host_params ) != START_MASTER ) && ( ++attempt < SLAVE_SETUP_RETRY ) );
@@ -315,7 +315,7 @@ namespace Jack
jack_info ( "Exiting '%s'", fParams.fName ); jack_info ( "Exiting '%s'", fParams.fName );
SetPacketType ( &fParams, KILL_MASTER ); SetPacketType ( &fParams, KILL_MASTER );
JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() );
session_params_t net_params; session_params_t net_params;
memset(&net_params, 0, sizeof ( session_params_t )); memset(&net_params, 0, sizeof ( session_params_t ));
SessionParamsHToN(&fParams, &net_params); SessionParamsHToN(&fParams, &net_params);
@@ -324,7 +324,7 @@ namespace Jack
jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't create socket : %s", StrError ( NET_ERROR_CODE ) );
if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) if ( mcast_socket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't send suicide request : %s", StrError ( NET_ERROR_CODE ) );
mcast_socket.Close(); mcast_socket.Close();
} }


@@ -343,25 +343,25 @@ namespace Jack
jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
//ask to the manager to properly remove the master //ask to the manager to properly remove the master
Exit(); Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit(); ThreadExit();
} }
else else
jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Error in master receive : %s", StrError ( NET_ERROR_CODE ) );
} }
packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
PacketHeaderNToH(header, header); PacketHeaderNToH(header, header);
return rx_bytes; return rx_bytes;
} }
int JackNetMasterInterface::Send ( size_t size, int flags ) int JackNetMasterInterface::Send ( size_t size, int flags )
{ {
int tx_bytes; int tx_bytes;
packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
PacketHeaderHToN(header, header); PacketHeaderHToN(header, header);
if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning )
{ {
net_error_t error = fSocket.GetError(); net_error_t error = fSocket.GetError();
@@ -370,7 +370,7 @@ namespace Jack
//fatal connection issue, exit //fatal connection issue, exit
jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) );
Exit(); Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine. // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit(); ThreadExit();
} }
@@ -379,7 +379,7 @@ namespace Jack
} }
return tx_bytes; return tx_bytes;
} }
bool JackNetMasterInterface::IsSynched() bool JackNetMasterInterface::IsSynched()
{ {
if (fParams.fNetworkMode == 's') { if (fParams.fNetworkMode == 's') {
@@ -388,7 +388,7 @@ namespace Jack
return true; return true;
} }
} }
int JackNetMasterInterface::SyncSend() int JackNetMasterInterface::SyncSend()
{ {
fTxHeader.fCycle++; fTxHeader.fCycle++;
@@ -446,12 +446,12 @@ namespace Jack
{ {
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); int rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) )
return rx_bytes; return rx_bytes;


fCycleOffset = fTxHeader.fCycle - rx_head->fCycle; fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
switch ( fParams.fNetworkMode ) switch ( fParams.fNetworkMode )
{ {
case 's' : case 's' :
@@ -464,7 +464,7 @@ namespace Jack
return 0; return 0;
else else
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (fCycleOffset > 2) { if (fCycleOffset > 2) {
jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
} }
@@ -479,8 +479,8 @@ namespace Jack
return 0; return 0;
else else
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (fCycleOffset != 1)
if (fCycleOffset != 1)
jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
break; break;


@@ -490,7 +490,7 @@ namespace Jack
// - here, receive data, we can't keep it queued on the rx buffer, // - here, receive data, we can't keep it queued on the rx buffer,
// - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
rx_bytes = Recv ( rx_head->fPacketSize, 0 ); rx_bytes = Recv ( rx_head->fPacketSize, 0 );
if (fCycleOffset != 0) if (fCycleOffset != 0)
jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset); jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
break; break;
@@ -499,7 +499,7 @@ namespace Jack
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
return rx_bytes; return rx_bytes;
} }
int JackNetMasterInterface::DataRecv() int JackNetMasterInterface::DataRecv()
{ {
int rx_bytes = 0; int rx_bytes = 0;
@@ -507,12 +507,12 @@ namespace Jack
uint recvd_midi_pckt = 0; uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0; uint recvd_audio_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer );
while ( !fRxHeader.fIsLastPckt ) while ( !fRxHeader.fIsLastPckt )
{ {
//how much data is queued on the rx buffer ? //how much data is queued on the rx buffer ?
rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); rx_bytes = Recv ( fParams.fMtu, MSG_PEEK );
if ( rx_bytes == SOCKET_ERROR ) if ( rx_bytes == SOCKET_ERROR )
return rx_bytes; return rx_bytes;
//if no data //if no data
@@ -564,7 +564,7 @@ namespace Jack
} }
return rx_bytes; return rx_bytes;
} }
void JackNetMasterInterface::EncodeSyncPacket() void JackNetMasterInterface::EncodeSyncPacket()
{ {
//this method contains every step of sync packet informations coding //this method contains every step of sync packet informations coding
@@ -632,9 +632,9 @@ namespace Jack


return true; return true;
} }
// Separate the connection protocol into two separated step // Separate the connection protocol into two separated step
bool JackNetSlaveInterface::InitConnection() bool JackNetSlaveInterface::InitConnection()
{ {
jack_log ( "JackNetSlaveInterface::InitConnection()" ); jack_log ( "JackNetSlaveInterface::InitConnection()" );
@@ -653,10 +653,10 @@ namespace Jack
return false; return false;
} }
while (status != NET_CONNECTED); while (status != NET_CONNECTED);
return true; return true;
} }
bool JackNetSlaveInterface::InitRendering() bool JackNetSlaveInterface::InitRendering()
{ {
jack_log("JackNetSlaveInterface::InitRendering()"); jack_log("JackNetSlaveInterface::InitRendering()");
@@ -670,8 +670,8 @@ namespace Jack
if (status == NET_ERROR) if (status == NET_ERROR)
return false; return false;
} }
while (status != NET_ROLLING);
while (status != NET_ROLLING);
return true; return true;
} }


@@ -695,7 +695,7 @@ namespace Jack
} }


//timeout on receive //timeout on receive
if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR )
if ( fSocket.SetTimeOut ( SLAVE_INIT_TIMEOUT ) == SOCKET_ERROR )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );


//disable local loop //disable local loop
@@ -712,7 +712,7 @@ namespace Jack
SessionParamsHToN(&fParams, &net_params); SessionParamsHToN(&fParams, &net_params);
if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR )
jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) );
//filter incoming packets : don't exit while no error is detected //filter incoming packets : don't exit while no error is detected
memset(&net_params, 0, sizeof ( session_params_t )); memset(&net_params, 0, sizeof ( session_params_t ));
rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
@@ -762,7 +762,7 @@ namespace Jack


void JackNetSlaveInterface::SetParams() void JackNetSlaveInterface::SetParams()
{ {
jack_log ( "JackNetSlaveInterface::SetParams" );
jack_log("JackNetSlaveInterface::SetParams");


JackNetInterface::SetParams(); JackNetInterface::SetParams();


@@ -801,7 +801,7 @@ namespace Jack
else else
jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) ); jack_error ( "Fatal error in slave receive : %s", StrError ( NET_ERROR_CODE ) );
} }
packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
PacketHeaderNToH(header, header); PacketHeaderNToH(header, header);
return rx_bytes; return rx_bytes;
@@ -812,7 +812,7 @@ namespace Jack
packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer); packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
PacketHeaderHToN(header, header); PacketHeaderHToN(header, header);
int tx_bytes = fSocket.Send ( fTxBuffer, size, flags ); int tx_bytes = fSocket.Send ( fTxBuffer, size, flags );
//handle errors //handle errors
if ( tx_bytes == SOCKET_ERROR ) if ( tx_bytes == SOCKET_ERROR )
{ {
@@ -842,7 +842,7 @@ namespace Jack
return rx_bytes; return rx_bytes;
} }
while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
return rx_bytes; return rx_bytes;
} }
@@ -953,7 +953,7 @@ namespace Jack
} }
return 0; return 0;
} }
//network sync------------------------------------------------------------------------ //network sync------------------------------------------------------------------------
void JackNetSlaveInterface::EncodeSyncPacket() void JackNetSlaveInterface::EncodeSyncPacket()
{ {
@@ -970,7 +970,7 @@ namespace Jack
//then others //then others
//... //...
} }
void JackNetSlaveInterface::DecodeSyncPacket() void JackNetSlaveInterface::DecodeSyncPacket()
{ {
//this method contains every step of sync packet informations decoding process //this method contains every step of sync packet informations decoding process


+ 2
- 0
common/JackNetTool.cpp View File

@@ -151,11 +151,13 @@ namespace Jack


void NetAudioBuffer::SetBuffer ( int index, sample_t* buffer ) void NetAudioBuffer::SetBuffer ( int index, sample_t* buffer )
{ {
assert(fPortBuffer);
fPortBuffer[index] = buffer; fPortBuffer[index] = buffer;
} }


sample_t* NetAudioBuffer::GetBuffer ( int index ) sample_t* NetAudioBuffer::GetBuffer ( int index )
{ {
assert(fPortBuffer);
return fPortBuffer[index]; return fPortBuffer[index];
} }




+ 22
- 19
common/JackWaitThreadedDriver.h View File

@@ -26,11 +26,11 @@


namespace Jack namespace Jack
{ {
/*! /*!
\brief To be used as a wrapper of JackNetDriver.
\brief To be used as a wrapper of JackNetDriver.


The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts.
The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts.
The Execute method will call the ProcessNull method until the decorated driver Init method returns. The Execute method will call the ProcessNull method until the decorated driver Init method returns.
A helper JackDriverStarter thread is used for that purpose. A helper JackDriverStarter thread is used for that purpose.
*/ */
@@ -38,54 +38,57 @@ A helper JackDriverStarter thread is used for that purpose.
class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver
{ {
private: private:
struct SERVER_EXPORT JackDriverStarter : public JackRunnableInterface
struct SERVER_EXPORT JackDriverStarter : public JackRunnableInterface
{ {
JackDriver* fDriver; JackDriver* fDriver;
JackThread fThread; JackThread fThread;
volatile bool fRunning; volatile bool fRunning;
JackDriverStarter(JackDriver* driver) JackDriverStarter(JackDriver* driver)
:fDriver(driver),fThread(this),fRunning(false) :fDriver(driver),fThread(this),fRunning(false)
{} {}
~JackDriverStarter() ~JackDriverStarter()
{ {
fThread.Kill(); fThread.Kill();
} }
int Start() int Start()
{ {
fRunning = false; fRunning = false;
return fThread.Start(); return fThread.Start();
} }
// JackRunnableInterface interface // JackRunnableInterface interface
bool Execute() bool Execute()
{ {
// Blocks until decorated driver is started (that is when it's Init method returns). // Blocks until decorated driver is started (that is when it's Init method returns).
fDriver->Initialize();
fRunning = true;
if (fDriver->Initialize()) {
fRunning = true;
} else {
jack_error("Initing net driver fails...");
}
return false; return false;
} }
}; };
JackDriverStarter fStarter; JackDriverStarter fStarter;
public: public:


JackWaitThreadedDriver(JackDriver* netdriver)
:JackThreadedDriver(netdriver),fStarter(netdriver)
JackWaitThreadedDriver(JackDriver* net_driver)
:JackThreadedDriver(net_driver), fStarter(net_driver)
{} {}
virtual ~JackWaitThreadedDriver() virtual ~JackWaitThreadedDriver()
{} {}
// JackRunnableInterface interface // JackRunnableInterface interface
bool Init(); bool Init();
bool Execute(); bool Execute();
};
};




} // end of namespace } // end of namespace


Loading…
Cancel
Save