aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-09-12 03:57:53 -0700
committerChris Robinson <[email protected]>2011-09-12 03:57:53 -0700
commit145bc6da6b836607c509204e3653688e97eb482c (patch)
tree7eb64afa1638e563c026c8eea5d35a1c8829ccc8
parent69b10e2d7c4817bca90b175b2d43609ff97686a9 (diff)
Be a bit more robust while handling the global device list
-rw-r--r--Alc/ALc.c83
-rw-r--r--OpenAL32/Include/alMain.h2
2 files changed, 39 insertions, 46 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index a6787df6..0916d0ee 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -361,8 +361,7 @@ static const ALCint alcEFXMinorVersion = 0;
static CRITICAL_SECTION ListLock;
/* Device List */
-static ALCdevice *g_pDeviceList = NULL;
-static ALCuint g_ulDeviceCount = 0;
+static ALCdevice *volatile DeviceList = NULL;
// Thread-local current context
static pthread_key_t LocalContext;
@@ -1327,7 +1326,7 @@ static ALCdevice *VerifyDevice(ALCdevice *device)
return NULL;
LockLists();
- tmpDevice = g_pDeviceList;
+ tmpDevice = DeviceList;
while(tmpDevice && tmpDevice != device)
tmpDevice = tmpDevice->next;
@@ -1530,7 +1529,7 @@ static ALCcontext *VerifyContext(ALCcontext *context)
ALCdevice *dev;
LockLists();
- dev = g_pDeviceList;
+ dev = DeviceList;
while(dev)
{
ALCcontext *tmp_ctx = dev->ContextList;
@@ -1652,30 +1651,29 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
device->NumUpdates = 1;
LockLists();
- if((err=ALCdevice_OpenCapture(device, deviceName)) == ALC_NO_ERROR)
- {
- device->next = g_pDeviceList;
- g_pDeviceList = device;
- g_ulDeviceCount++;
- }
- else
+ if((err=ALCdevice_OpenCapture(device, deviceName)) != ALC_NO_ERROR)
{
+ UnlockLists();
DeleteCriticalSection(&device->Mutex);
free(device);
- device = NULL;
alcSetError(NULL, err);
+ return NULL;
}
UnlockLists();
+ do {
+ device->next = DeviceList;
+ } while(!CompExchangePtr((void**)&DeviceList, device->next, device));
+
return device;
}
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *pDevice)
{
- ALCdevice **list;
+ ALCdevice *volatile*list;
LockLists();
- list = &g_pDeviceList;
+ list = &DeviceList;
while(*list && *list != pDevice)
list = &(*list)->next;
@@ -1687,8 +1685,6 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *pDevice)
}
*list = (*list)->next;
- g_ulDeviceCount--;
-
UnlockLists();
LockDevice(pDevice);
@@ -2510,22 +2506,20 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
// Find a playback device to open
LockLists();
- if((err=ALCdevice_OpenPlayback(device, deviceName)) == ALC_NO_ERROR)
+ if((err=ALCdevice_OpenPlayback(device, deviceName)) != ALC_NO_ERROR)
{
- device->next = g_pDeviceList;
- g_pDeviceList = device;
- g_ulDeviceCount++;
- }
- else
- {
- // No suitable output device found
+ UnlockLists();
DeleteCriticalSection(&device->Mutex);
free(device);
- device = NULL;
alcSetError(NULL, err);
+ return NULL;
}
UnlockLists();
+ do {
+ device->next = DeviceList;
+ } while(!CompExchangePtr((void**)&DeviceList, device->next, device));
+
return device;
}
@@ -2535,11 +2529,11 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
*/
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *pDevice)
{
- ALCdevice **list;
+ ALCdevice *volatile*list;
ALCcontext *ctx;
LockLists();
- list = &g_pDeviceList;
+ list = &DeviceList;
while(*list && *list != pDevice)
list = &(*list)->next;
@@ -2551,7 +2545,6 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *pDevice)
}
*list = (*list)->next;
- g_ulDeviceCount--;
UnlockLists();
if((ctx=pDevice->ContextList) != NULL)
@@ -2633,14 +2626,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void)
device->Bs2bLevel = GetConfigValueInt(NULL, "cf_level", 0);
// Open the "backend"
- LockLists();
ALCdevice_OpenPlayback(device, "Loopback");
-
- device->next = g_pDeviceList;
- g_pDeviceList = device;
- g_ulDeviceCount++;
- UnlockLists();
-
+ do {
+ device->next = DeviceList;
+ } while(!CompExchangePtr((void**)&DeviceList, device->next, device));
return device;
}
@@ -2704,21 +2693,25 @@ static void ReleaseALC(ALCboolean doclose)
if(doclose)
{
- if(g_ulDeviceCount > 0)
- WARN("Closing %u device%s\n", g_ulDeviceCount, (g_ulDeviceCount>1)?"s":"");
-
- while(g_pDeviceList)
+ ALCdevice *dev;
+ while((dev=DeviceList) != NULL)
{
- if(g_pDeviceList->IsCaptureDevice)
- alcCaptureCloseDevice(g_pDeviceList);
- else
- alcCloseDevice(g_pDeviceList);
+ WARN("Closing device %p\n", dev);
+ if(!dev->IsCaptureDevice) alcCloseDevice(dev);
+ else alcCaptureCloseDevice(dev);
}
}
else
{
- if(g_ulDeviceCount > 0)
- WARN("%u device%s not closed\n", g_ulDeviceCount, (g_ulDeviceCount>1)?"s":"");
+ ALCdevice *dev;
+ if((dev=DeviceList) != NULL)
+ {
+ ALCuint num = 0;
+ do {
+ num++;
+ } while((dev=dev->next) != NULL);
+ WARN("%u device%s not closed\n", num, (num>1)?"s":"");
+ }
}
}
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index f624cc09..5b770691 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -574,7 +574,7 @@ struct ALCdevice_struct
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use
- ALCdevice *next;
+ ALCdevice *volatile next;
};
#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b)))