diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index a3546a2a..6ef5936e 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -1210,8 +1210,13 @@ EXPORT bool jackctl_server_unload_internal( EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { - driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); - return (driver_ptr->info != 0); + if (server_ptr->engine->IsRunning()) { + jack_error("cannot add a slave in a running server"); + return false; + } else { + driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); + return (driver_ptr->info != 0); + } } else { return false; } @@ -1220,9 +1225,14 @@ EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) { if (server_ptr->engine != NULL) { - server_ptr->engine->RemoveSlave(driver_ptr->info); - delete driver_ptr->info; - return true; + if (server_ptr->engine->IsRunning()) { + jack_error("cannot remove a slave from a running server"); + return false; + } else { + server_ptr->engine->RemoveSlave(driver_ptr->info); + delete driver_ptr->info; + return true; + } } else { return false; } diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 046b2e46..657524bd 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -47,6 +47,7 @@ JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* en fBeginDateUst = 0; fDelayedUsecs = 0.f; fIsMaster = true; + fIsRunning = false; } JackDriver::JackDriver() @@ -56,6 +57,7 @@ JackDriver::JackDriver() fGraphManager = NULL; fBeginDateUst = 0; fIsMaster = true; + fIsRunning = false; } JackDriver::~JackDriver() @@ -288,6 +290,7 @@ int JackDriver::ProcessSlaves() JackDriverInterface* slave = *it; if (slave->Process() < 0) res = -1; + } return res; } @@ -327,6 +330,7 @@ int JackDriver::Start() if (fIsMaster) { fEngineControl->InitFrameTime(); } + fIsRunning = true; return 0; } @@ -350,6 +354,7 @@ int JackDriver::StartSlaves() int JackDriver::Stop() { + fIsRunning = false; return 0; } diff --git a/common/JackDriver.h b/common/JackDriver.h index 3fd7b860..68f937c2 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -97,6 +97,7 @@ class SERVER_EXPORT JackDriverInterface virtual int ProcessSlaves() = 0; virtual bool IsRealTime() const = 0; + virtual bool IsRunning() const = 0; }; /*! @@ -134,6 +135,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface JackClientControl fClientControl; std::list fSlaveList; bool fIsMaster; + bool fIsRunning; void CycleIncTime(); void CycleTakeBeginTime(); @@ -210,6 +212,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; + virtual bool IsRunning() const { return fIsRunning; } virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one }; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 96bfe068..cd1915fb 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -57,8 +57,8 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio JackFreewheelDriver *freewheelDriver = new JackFreewheelDriver(fEngine, GetSynchroTable()); fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver); - fFreewheelDriver = freewheelDriver; + fFreewheelDriver = freewheelDriver; fDriverInfo = new JackDriverInfo(); fAudioDriver = NULL; fFreewheel = false; @@ -188,7 +188,18 @@ int JackServer::Start() int JackServer::Stop() { jack_log("JackServer::Stop"); - return fAudioDriver->Stop(); + if (fFreewheel) { + return fThreadedFreewheelDriver->Stop(); + } else { + return fAudioDriver->Stop(); + } +} + +bool JackServer::IsRunning() +{ + jack_log("JackServer::IsRunning"); + assert(fAudioDriver); + return fAudioDriver->IsRunning(); } int JackServer::SetBufferSize(jack_nframes_t buffer_size) @@ -281,7 +292,6 @@ void JackServer::Notify(int refnum, int notify, int value) case kXRunCallback: fEngine->NotifyXRun(refnum); break; - } } diff --git a/common/JackServer.h b/common/JackServer.h index e7437bad..bdbd8ea8 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -71,6 +71,7 @@ class SERVER_EXPORT JackServer int Start(); int Stop(); + bool IsRunning(); // RT thread void Notify(int refnum, int notify, int value); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 52e49197..88323fe5 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -152,6 +152,11 @@ bool JackThreadedDriver::IsRealTime() const return fDriver->IsRealTime(); } +bool JackThreadedDriver::IsRunning() const +{ + return fDriver->IsRunning(); +} + int JackThreadedDriver::Start() { jack_log("JackThreadedDriver::Start"); @@ -171,9 +176,9 @@ int JackThreadedDriver::Start() int JackThreadedDriver::Stop() { jack_log("JackThreadedDriver::Stop"); - + switch (fThread.GetStatus()) { - + // Kill the thread in Init phase case JackThread::kStarting: case JackThread::kIniting: @@ -182,15 +187,15 @@ int JackThreadedDriver::Stop() return -1; } break; - + // Stop when the thread cycle is finished case JackThread::kRunning: if (fThread.Stop() < 0) { - jack_error("Cannot stop thread"); + jack_error("Cannot stop thread"); return -1; } break; - + default: break; } @@ -218,7 +223,7 @@ bool JackThreadedDriver::Init() if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { - set_threaded_log_function(); + set_threaded_log_function(); } } return true; diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index f7bbf2d0..92ec1d26 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -38,14 +38,14 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi JackThread fThread; JackDriver* fDriver; - + public: JackThreadedDriver(JackDriver* driver); virtual ~JackThreadedDriver(); virtual int Open(); - + virtual int Open (bool capturing, bool playing, int inchannels, @@ -54,7 +54,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, - jack_nframes_t playback_latency) + jack_nframes_t playback_latency) { return -1; } @@ -70,34 +70,35 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi jack_nframes_t capture_latency, jack_nframes_t playback_latency); virtual int Close(); - + virtual int Process(); virtual int ProcessNull(); - + virtual int Attach(); virtual int Detach(); - + virtual int Read(); virtual int Write(); - + virtual int Start(); virtual int Stop(); virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); - + virtual void SetMaster(bool onoff); virtual bool GetMaster(); virtual void AddSlave(JackDriverInterface* slave); virtual void RemoveSlave(JackDriverInterface* slave); virtual std::list GetSlaves(); virtual int ProcessSlaves(); - + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; - + virtual bool IsRunning() const; + // JackRunnableInterface interface virtual bool Execute(); virtual bool Init(); diff --git a/common/jack/control.h b/common/jack/control.h index 7ec5c521..b2c53ab0 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -4,7 +4,7 @@ Copyright (C) 2008 Nedko Arnaudov Copyright (C) 2008 GRAME - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. @@ -86,10 +86,10 @@ extern "C" { * @{ */ -/** +/** * Call this function to setup process signal handling. As a general * rule, it is required for proper operation for the server object. - * + * * @param flags signals setup flags, use 0 for none. Currently no * flags are defined * @@ -99,9 +99,9 @@ sigset_t jackctl_setup_signals( unsigned int flags); -/** +/** * Call this function to wait on a signal set. - * + * * @param signals signals set to wait on */ void @@ -123,21 +123,21 @@ jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)); -/** +/** * Call this function to destroy server object. - * + * * @param server server object handle to destroy */ void jackctl_server_destroy( jackctl_server_t * server); -/** +/** * Call this function to open JACK server - * + * * @param server server object handle * @param driver driver to use - * + * * @return success status: true - success, false - fail */ bool @@ -145,43 +145,43 @@ jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** * Call this function to start JACK server - * + * * @param server server object handle - * + * * @return success status: true - success, false - fail */ bool jackctl_server_start( jackctl_server_t * server); -/** +/** * Call this function to stop JACK server - * + * * @param server server object handle - * + * * @return success status: true - success, false - fail */ bool jackctl_server_stop( jackctl_server_t * server); -/** +/** * Call this function to close JACK server - * + * * @param server server object handle - * + * * @return success status: true - success, false - fail */ bool jackctl_server_close( jackctl_server_t * server); -/** +/** * Call this function to get list of available drivers. List node data * pointers is a driver object handle (::jackctl_driver_t). - * + * * @param server server object handle to get drivers for * * @return Single linked list of driver object handles. Must not be @@ -191,10 +191,10 @@ const JSList * jackctl_server_get_drivers_list( jackctl_server_t * server); -/** +/** * Call this function to get list of server parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param server server object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -204,10 +204,10 @@ const JSList * jackctl_server_get_parameters( jackctl_server_t * server); -/** +/** * Call this function to get list of available internal clients. List node data * pointers is a internal client object handle (::jackctl_internal_t). - * + * * @param server server object handle to get internal clients for * * @return Single linked list of internal client object handles. Must not be @@ -217,12 +217,13 @@ const JSList * jackctl_server_get_internals_list( jackctl_server_t * server); -/** +/** * Call this function to load one internal client. - * + * (can be used when the server is running) + * * @param server server object handle * @param internal internal to use - * + * * @return success status: true - success, false - fail */ bool @@ -230,12 +231,13 @@ jackctl_server_load_internal( jackctl_server_t * server, jackctl_internal_t * internal); -/** +/** * Call this function to unload one internal client. - * + * (can be used when the server is running) + * * @param server server object handle * @param internal internal to unload - * + * * @return success status: true - success, false - fail */ bool @@ -243,46 +245,50 @@ jackctl_server_unload_internal( jackctl_server_t * server, jackctl_internal_t * internal); -/** +/** * Call this function to add a slave in the driver slave list. - * + * (cannot be used when the server is running that is between + * jackctl_server_start and jackctl_server_stop) + * * @param server server object handle * @param driver driver to add in the driver slave list. - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_add_slave(jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** * Call this function to remove a slave from the driver slave list. - * + * (cannot be used when the server is running that is between + * jackctl_server_start and jackctl_server_stop) + * * @param server server object handle * @param driver driver to remove from the driver slave list. - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_remove_slave(jackctl_server_t * server, jackctl_driver_t * driver); -/** +/** * Call this function to switch master driver. - * + * * @param server server object handle * @param driver driver to switch to - * + * * @return success status: true - success, false - fail - */ -bool + */ +bool jackctl_server_switch_master(jackctl_server_t * server, jackctl_driver_t * driver); - -/** + +/** * Call this function to get name of driver. - * + * * @param driver driver object handle to get name of * * @return driver name. Must not be modified. Always same for same @@ -292,10 +298,10 @@ const char * jackctl_driver_get_name( jackctl_driver_t * driver); -/** +/** * Call this function to get list of driver parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param driver driver object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -305,9 +311,9 @@ const JSList * jackctl_driver_get_parameters( jackctl_driver_t * driver); -/** +/** * Call this function to get name of internal client. - * + * * @param internal internal object handle to get name of * * @return internal name. Must not be modified. Always same for same @@ -317,10 +323,10 @@ const char * jackctl_internal_get_name( jackctl_internal_t * internal); -/** +/** * Call this function to get list of internal parameters. List node data * pointers is a parameter object handle (::jackctl_parameter_t). - * + * * @param internal internal object handle to get parameters for * * @return Single linked list of parameter object handles. Must not be @@ -330,9 +336,9 @@ const JSList * jackctl_internal_get_parameters( jackctl_internal_t * internal); -/** +/** * Call this function to get parameter name. - * + * * @param parameter parameter object handle to get name of * * @return parameter name. Must not be modified. Always same for same @@ -342,9 +348,9 @@ const char * jackctl_parameter_get_name( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter short description. - * + * * @param parameter parameter object handle to get short description of * * @return parameter short description. Must not be modified. Always @@ -354,9 +360,9 @@ const char * jackctl_parameter_get_short_description( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter long description. - * + * * @param parameter parameter object handle to get long description of * * @return parameter long description. Must not be modified. Always @@ -366,9 +372,9 @@ const char * jackctl_parameter_get_long_description( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter type. - * + * * @param parameter parameter object handle to get type of * * @return parameter type. Always same for same parameter object. @@ -377,21 +383,21 @@ jackctl_param_type_t jackctl_parameter_get_type( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter character. - * + * * @param parameter parameter object handle to get character of * - * @return character. + * @return character. */ char jackctl_parameter_get_id( jackctl_parameter_t * parameter); -/** +/** * Call this function to check whether parameter has been set, or its * default value is being used. - * + * * @param parameter parameter object handle to check * * @return true - parameter is set, false - parameter is using default @@ -401,9 +407,9 @@ bool jackctl_parameter_is_set( jackctl_parameter_t * parameter); -/** +/** * Call this function to reset parameter to its default value. - * + * * @param parameter parameter object handle to reset value of * * @return success status: true - success, false - fail @@ -412,9 +418,9 @@ bool jackctl_parameter_reset( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter value. - * + * * @param parameter parameter object handle to get value of * * @return parameter value. @@ -423,9 +429,9 @@ union jackctl_parameter_value jackctl_parameter_get_value( jackctl_parameter_t * parameter); -/** +/** * Call this function to set parameter value. - * + * * @param parameter parameter object handle to get value of * @param value_ptr pointer to variable containing parameter value * @@ -436,9 +442,9 @@ jackctl_parameter_set_value( jackctl_parameter_t * parameter, const union jackctl_parameter_value * value_ptr); -/** +/** * Call this function to get parameter default value. - * + * * @param parameter parameter object handle to get default value of * * @return parameter default value. @@ -446,10 +452,10 @@ jackctl_parameter_set_value( union jackctl_parameter_value jackctl_parameter_get_default_value( jackctl_parameter_t * parameter); - -/** + +/** * Call this function check whether parameter has range constraint. - * + * * @param parameter object handle of parameter to check * * @return whether parameter has range constraint. @@ -458,9 +464,9 @@ bool jackctl_parameter_has_range_constraint( jackctl_parameter_t * parameter); -/** +/** * Call this function check whether parameter has enumeration constraint. - * + * * @param parameter object handle of parameter to check * * @return whether parameter has enumeration constraint. @@ -469,9 +475,9 @@ bool jackctl_parameter_has_enum_constraint( jackctl_parameter_t * parameter); -/** +/** * Call this function get how many enumeration values parameter has. - * + * * @param parameter object handle of parameter * * @return number of enumeration values @@ -480,9 +486,9 @@ uint32_t jackctl_parameter_get_enum_constraints_count( jackctl_parameter_t * parameter); -/** +/** * Call this function to get parameter enumeration value. - * + * * @param parameter object handle of parameter * @param index index of parameter enumeration value * @@ -493,9 +499,9 @@ jackctl_parameter_get_enum_constraint_value( jackctl_parameter_t * parameter, uint32_t index); -/** +/** * Call this function to get parameter enumeration value description. - * + * * @param parameter object handle of parameter * @param index index of parameter enumeration value * @@ -506,9 +512,9 @@ jackctl_parameter_get_enum_constraint_description( jackctl_parameter_t * parameter, uint32_t index); -/** +/** * Call this function to get parameter range. - * + * * @param parameter object handle of parameter * @param min_ptr pointer to variable receiving parameter minimum value * @param max_ptr pointer to variable receiving parameter maximum value @@ -519,10 +525,10 @@ jackctl_parameter_get_range_constraint( union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr); -/** +/** * Call this function to check whether parameter constraint is strict, * i.e. whether supplying non-matching value will not work for sure. - * + * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. @@ -531,11 +537,11 @@ bool jackctl_parameter_constraint_is_strict( jackctl_parameter_t * parameter); -/** +/** * Call this function to check whether parameter has fake values, * i.e. values have no user meaningful meaning and only value * description is meaningful to user. - * + * * @param parameter parameter object handle to check * * @return whether parameter constraint is strict. @@ -544,9 +550,9 @@ bool jackctl_parameter_constraint_is_fake_value( jackctl_parameter_t * parameter); -/** +/** * Call this function to log an error message. - * + * * @param format string */ void @@ -554,9 +560,9 @@ jack_error( const char *format, ...); -/** +/** * Call this function to log an information message. - * + * * @param format string */ void @@ -564,10 +570,10 @@ jack_info( const char *format, ...); -/** +/** * Call this function to log an information message but only when * verbose mode is enabled. - * + * * @param format string */ void