diff options
author | Chris Robinson <[email protected]> | 2019-04-09 20:48:01 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-04-09 20:48:01 -0700 |
commit | 460a01443c925013f3f9dadeab5d07373ac5c894 (patch) | |
tree | 10d4f7bbe3eeec95f462403574a335b9e9b05495 | |
parent | e6daab51e8cd06c66680eb88e4b83ca3fb5918b0 (diff) |
Add macros to stop exceptions from leaving API functions
Effectively makes the functions act as noexcept, since there's no meaningful
reason to propogate exceptions from "C" functions. Currently only applied to
ALC functions, but can incrementally be applied to AL functions too. In the
future, this could also handle ALC and AL errors with unique exception types
(functions that utilize this behavior would need to ensure proper cleanup).
-rw-r--r-- | Alc/alc.cpp | 68 | ||||
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | common/alexcpt.h | 11 |
3 files changed, 74 insertions, 6 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index 887da871..d72bb744 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -61,6 +61,7 @@ #include "cpu_caps.h" #include "compat.h" #include "threads.h" +#include "alexcpt.h" #include "almalloc.h" #include "backends/base.h" @@ -2702,11 +2703,13 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) * Return last ALC generated error code for the given device */ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(dev) return dev->LastError.exchange(ALC_NO_ERROR); return LastNullDeviceError.exchange(ALC_NO_ERROR); } +END_API_FUNC /* alcSuspendContext @@ -2714,6 +2717,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) * Suspends updates for the given context */ ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context) +START_API_FUNC { if(!SuspendDefers) return; @@ -2724,12 +2728,14 @@ ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context) else ALCcontext_DeferUpdates(ctx.get()); } +END_API_FUNC /* alcProcessContext * * Resumes processing updates for the given context */ ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context) +START_API_FUNC { if(!SuspendDefers) return; @@ -2740,6 +2746,7 @@ ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context) else ALCcontext_ProcessUpdates(ctx.get()); } +END_API_FUNC /* alcGetString @@ -2747,6 +2754,7 @@ ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context) * Returns information about the device, and error strings */ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param) +START_API_FUNC { const ALCchar *value = nullptr; DeviceRef dev; @@ -2851,6 +2859,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para return value; } +END_API_FUNC static inline ALCsizei NumAttrsForDevice(ALCdevice *device) @@ -3178,6 +3187,7 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC * Returns information about the device and the version of OpenAL */ ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(size <= 0 || values == nullptr) @@ -3185,8 +3195,10 @@ ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsi else GetIntegerv(dev.get(), param, size, values); } +END_API_FUNC ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(size <= 0 || values == nullptr) @@ -3316,6 +3328,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, } } } +END_API_FUNC /* alcIsExtensionPresent @@ -3323,6 +3336,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, * Determines if there is support for a particular extension */ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!extName) @@ -3347,6 +3361,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A } return ALC_FALSE; } +END_API_FUNC /* alcGetProcAddress @@ -3354,6 +3369,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A * Retrieves the function address for a particular extension function */ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName) +START_API_FUNC { if(!funcName) { @@ -3368,9 +3384,9 @@ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar return func.address; } } - return nullptr; } +END_API_FUNC /* alcGetEnumValue @@ -3378,6 +3394,7 @@ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar * Get the value for a particular ALC enumeration name */ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName) +START_API_FUNC { if(!enumName) { @@ -3392,9 +3409,9 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e return enm.value; } } - return 0; } +END_API_FUNC /* alcCreateContext @@ -3402,6 +3419,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e * Create and attach a context to the given device. */ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList) +START_API_FUNC { /* Explicitly hold the list lock while taking the StateLock in case the * device is asynchronously destroyed, to ensure this new context is @@ -3492,12 +3510,14 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin TRACE("Created context %p\n", context.get()); return context.get(); } +END_API_FUNC /* alcDestroyContext * * Remove a context from its device */ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) +START_API_FUNC { std::unique_lock<std::recursive_mutex> listlock{ListLock}; auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context); @@ -3525,6 +3545,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) } listlock.unlock(); } +END_API_FUNC /* alcGetCurrentContext @@ -3532,21 +3553,22 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) * Returns the currently active context on the calling thread */ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) +START_API_FUNC { ALCcontext *Context{LocalContext.get()}; if(!Context) Context = GlobalContext.load(); return Context; } +END_API_FUNC /* alcGetThreadContext * * Returns the currently active thread-local context */ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) -{ - return LocalContext.get(); -} - +START_API_FUNC +{ return LocalContext.get(); } +END_API_FUNC /* alcMakeContextCurrent * @@ -3554,6 +3576,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) * thread-local context for the calling thread. */ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) +START_API_FUNC { /* context must be valid or nullptr */ ContextRef ctx; @@ -3582,12 +3605,14 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) return ALC_TRUE; } +END_API_FUNC /* alcSetThreadContext * * Makes the given context the active context for the current thread */ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) +START_API_FUNC { /* context must be valid or nullptr */ ContextRef ctx; @@ -3606,6 +3631,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) return ALC_TRUE; } +END_API_FUNC /* alcGetContextsDevice @@ -3613,6 +3639,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) * Returns the device that a particular context is attached to */ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context) +START_API_FUNC { ContextRef ctx{VerifyContext(Context)}; if(!ctx) @@ -3622,6 +3649,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context) } return ctx->Device; } +END_API_FUNC /* alcOpenDevice @@ -3629,6 +3657,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context) * Opens the named device. */ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) +START_API_FUNC { DO_INITCONFIG(); @@ -3818,12 +3847,14 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) TRACE("Created device %p, \"%s\"\n", device.get(), device->DeviceName.c_str()); return device.get(); } +END_API_FUNC /* alcCloseDevice * * Closes the given device. */ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) +START_API_FUNC { std::unique_lock<std::recursive_mutex> listlock{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device); @@ -3871,12 +3902,14 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) return ALC_TRUE; } +END_API_FUNC /************************************************ * ALC capture functions ************************************************/ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples) +START_API_FUNC { DO_INITCONFIG(); @@ -3939,8 +3972,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, TRACE("Created device %p, \"%s\"\n", device.get(), device->DeviceName.c_str()); return device.get(); } +END_API_FUNC ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) +START_API_FUNC { std::unique_lock<std::recursive_mutex> listlock{ListLock}; auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device); @@ -3968,8 +4003,10 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) return ALC_TRUE; } +END_API_FUNC ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Capture) @@ -3992,8 +4029,10 @@ ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) } } } +END_API_FUNC ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Capture) @@ -4006,8 +4045,10 @@ ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) dev->Flags &= ~DEVICE_RUNNING; } } +END_API_FUNC ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Capture) @@ -4025,6 +4066,7 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, if(err != ALC_NO_ERROR) alcSetError(dev.get(), err); } +END_API_FUNC /************************************************ @@ -4036,6 +4078,7 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, * Open a loopback device, for manual rendering. */ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName) +START_API_FUNC { DO_INITCONFIG(); @@ -4096,12 +4139,14 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN TRACE("Created device %p\n", device.get()); return device.get(); } +END_API_FUNC /* alcIsRenderFormatSupportedSOFT * * Determines if the loopback device supports the given format for rendering. */ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Loopback) @@ -4116,6 +4161,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device return ALC_FALSE; } +END_API_FUNC /* alcRenderSamplesSOFT * @@ -4123,6 +4169,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device * attributes given to alcCreateContext. */ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Loopback) @@ -4135,6 +4182,7 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL aluMixData(dev.get(), buffer, samples); } } +END_API_FUNC /************************************************ @@ -4146,6 +4194,7 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL * Pause the DSP to stop audio processing. */ ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Playback) @@ -4159,12 +4208,14 @@ ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) dev->Flags |= DEVICE_PAUSED; } } +END_API_FUNC /* alcDeviceResumeSOFT * * Resume the DSP to restart audio processing. */ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type != Playback) @@ -4188,6 +4239,7 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) } dev->Flags |= DEVICE_RUNNING; } +END_API_FUNC /************************************************ @@ -4199,6 +4251,7 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) * Gets a string parameter at the given index. */ ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index) +START_API_FUNC { DeviceRef dev{VerifyDevice(device)}; if(!dev || dev->Type == Capture) @@ -4218,12 +4271,14 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum return nullptr; } +END_API_FUNC /* alcResetDeviceSOFT * * Resets the given device output, using the specified attribute list. */ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs) +START_API_FUNC { std::unique_lock<std::recursive_mutex> listlock{ListLock}; DeviceRef dev{VerifyDevice(device)}; @@ -4252,3 +4307,4 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi aluHandleDisconnect(dev.get(), "Device start failure"); return ALC_FALSE; } +END_API_FUNC diff --git a/CMakeLists.txt b/CMakeLists.txt index f5884a0f..411ae1ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -642,6 +642,7 @@ ENDIF() SET(COMMON_OBJS common/alcomplex.cpp common/alcomplex.h + common/alexcpt.h common/almalloc.cpp common/almalloc.h common/alnumeric.h diff --git a/common/alexcpt.h b/common/alexcpt.h new file mode 100644 index 00000000..3e31667e --- /dev/null +++ b/common/alexcpt.h @@ -0,0 +1,11 @@ +#ifndef ALEXCPT_H +#define ALEXCPT_H + +#include <exception> + + +#define START_API_FUNC try + +#define END_API_FUNC catch(...) { std::terminate(); } + +#endif /* ALEXCPT_H */ |