From 13f0a7d5fe9e57975a7fc02bb321e2d4c50780d7 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 13 Nov 2009 14:46:08 +0000 Subject: [PATCH] Memory allocation error checking in server for RPC. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3782 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 3 +- common/JackEngine.cpp | 6 +-- common/JackEngineControl.h | 4 +- common/JackLockedEngine.h | 75 ++++++++++++++++++++++++++++++- common/JackServerAPI.cpp | 24 ++++++---- common/JackWeakAPI.cpp | 2 +- macosx/coreaudio/JackCoreAudioAdapter.cpp | 4 -- macosx/coreaudio/JackCoreAudioDriver.cpp | 4 -- 8 files changed, 98 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d8095dc..05e340c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,7 +28,8 @@ Paul Davis 2009-11-13 Stephane Letz * Better memory allocation error checking in ringbuffer.c, weak import improvements. - * Memory allocation error checking for jack_client_new and jack_client_open. + * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). + * Memory allocation error checking in server for RPC. 2009-11-12 Stephane Letz diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 8e798e5e..3a0bb2ae 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -307,12 +307,12 @@ void JackEngine::NotifyFreewheel(bool onoff) { if (onoff) { // Save RT state - fEngineControl->fFWRealTime = fEngineControl->fRealTime; + fEngineControl->fSavedRealTime = fEngineControl->fRealTime; fEngineControl->fRealTime = false; } else { // Restore RT state - fEngineControl->fRealTime = fEngineControl->fFWRealTime; - fEngineControl->fFWRealTime = false; + fEngineControl->fRealTime = fEngineControl->fSavedRealTime; + fEngineControl->fSavedRealTime = false; } NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, "", 0, 0); } diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 47c04d35..326e3b7f 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -58,7 +58,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem float fXrunDelayedUsecs; bool fTimeOut; bool fRealTime; - bool fFWRealTime; // RT state saved and restored during Freewheel mode + bool fSavedRealTime; // RT state saved and restored during Freewheel mode int fServerPriority; int fClientPriority; int fMaxClientPriority; @@ -101,7 +101,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem fTimeOut = (timeout > 0); fTimeOutUsecs = timeout * 1000; fRealTime = rt; - fFWRealTime = false; + fSavedRealTime = false; fServerPriority = priority; fClientPriority = (rt) ? priority - 5 : 0; fMaxClientPriority = (rt) ? priority - 1 : 0; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index d1d9d3d1..07ba57bc 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -26,10 +26,29 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { +#define TRY_CALL \ + try { \ + +#define CATCH_EXCEPTION_RETURN \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + return -1; \ + } catch (...) { \ + jack_error("Unknown error..."); \ + return -1; \ + } \ + +#define CATCH_ENGINE_EXCEPTION \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + } catch (...) { \ + jack_error("Unknown error..."); \ + } \ + /*! \brief Locked Engine, access to methods is serialized using a mutex. */ - + class SERVER_EXPORT JackLockedEngine : public JackLockAble { private: @@ -47,108 +66,146 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int Open() { // No lock needed + TRY_CALL return fEngine.Open(); + CATCH_EXCEPTION_RETURN } int Close() { // No lock needed + TRY_CALL return fEngine.Close(); + CATCH_EXCEPTION_RETURN } // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { + TRY_CALL JackLock lock(this); return fEngine.ClientCheck(name, name_res, protocol, options, status); + CATCH_EXCEPTION_RETURN } int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); + CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); + CATCH_EXCEPTION_RETURN } int ClientExternalClose(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalClose(refnum); + CATCH_EXCEPTION_RETURN } int ClientInternalClose(int refnum, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalClose(refnum, wait); + CATCH_EXCEPTION_RETURN } int ClientActivate(int refnum, bool is_real_time) { + TRY_CALL JackLock lock(this); return fEngine.ClientActivate(refnum, is_real_time); + CATCH_EXCEPTION_RETURN } int ClientDeactivate(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientDeactivate(refnum); + CATCH_EXCEPTION_RETURN } // Internal client management int GetInternalClientName(int int_ref, char* name_res) { + TRY_CALL JackLock lock(this); return fEngine.GetInternalClientName(int_ref, name_res); + CATCH_EXCEPTION_RETURN } int InternalClientHandle(const char* client_name, int* status, int* int_ref) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientHandle(client_name, status, int_ref); + CATCH_EXCEPTION_RETURN } int InternalClientUnload(int refnum, int* status) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientUnload(refnum, status); + CATCH_EXCEPTION_RETURN } // Port management int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) { + TRY_CALL JackLock lock(this); return fEngine.PortRegister(refnum, name, type, flags, buffer_size, port); + CATCH_EXCEPTION_RETURN } int PortUnRegister(int refnum, jack_port_id_t port) { + TRY_CALL JackLock lock(this); return fEngine.PortUnRegister(refnum, port); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortRename(int refnum, jack_port_id_t port, const char* name) { + TRY_CALL JackLock lock(this); return fEngine.PortRename(refnum, port, name); + CATCH_EXCEPTION_RETURN } // Graph @@ -167,46 +224,62 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyXRun(int refnum) { + TRY_CALL JackLock lock(this); fEngine.NotifyXRun(refnum); + CATCH_ENGINE_EXCEPTION } void NotifyGraphReorder() { + TRY_CALL JackLock lock(this); fEngine.NotifyGraphReorder(); + CATCH_ENGINE_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { + TRY_CALL JackLock lock(this); fEngine.NotifyBufferSize(buffer_size); + CATCH_ENGINE_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { + TRY_CALL JackLock lock(this); fEngine.NotifySampleRate(sample_rate); + CATCH_ENGINE_EXCEPTION } void NotifyFreewheel(bool onoff) { + TRY_CALL JackLock lock(this); fEngine.NotifyFreewheel(onoff); + CATCH_ENGINE_EXCEPTION } void NotifyFailure(int code, const char* reason) { + TRY_CALL JackLock lock(this); fEngine.NotifyFailure(code, reason); + CATCH_ENGINE_EXCEPTION } int GetClientPID(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientPID(name); + CATCH_EXCEPTION_RETURN } int GetClientRefNum(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientRefNum(name); + CATCH_EXCEPTION_RETURN } }; diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index 1fe4d1c1..e8e6c021 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -105,14 +105,22 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - va_list ap; - va_start(ap, status); - jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); - va_end(ap); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + va_list ap; + va_start(ap, status); + jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); + va_end(ap); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch(std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT int jack_client_close(jack_client_t* ext_client) diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 34154f2d..81e21d35 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -75,7 +75,7 @@ void *load_jack_function(const char *fn_name) static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) return (*fn)arguments; \ - else return (return_type)0; \ + else return (return_type)-1; \ } #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 466964da..c76a385a 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -721,10 +721,6 @@ int JackCoreAudioAdapter::SetupBuffers(int inchannels) // Prepare buffers fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fInputData->mBuffers[i].mNumberChannels = 1; diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index d152546b..37c4cf1a 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1163,10 +1163,6 @@ int JackCoreAudioDriver::SetupBuffers(int inchannels) { // Prepare buffers fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fJackInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fJackInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; -- 2.11.4.GIT