static HRESULT WINAPI BaseMemAllocator_ReleaseBuffer(IMemAllocator * iface, IMediaSample * pSample) { BaseMemAllocator *This = impl_from_IMemAllocator(iface); StdMediaSample2 * pStdSample = unsafe_impl_from_IMediaSample(pSample); HRESULT hr = S_OK; TRACE("(%p)->(%p)\n", This, pSample); /* FIXME: make sure that sample is currently on the used list */ /* FIXME: we should probably check the ref count on the sample before freeing * it to make sure that it is not still in use */ EnterCriticalSection(This->pCritSect); { if (!This->bCommitted) ERR("Releasing a buffer when the allocator is not committed?!?\n"); /* remove from used_list */ list_remove(&pStdSample->listentry); list_add_head(&This->free_list, &pStdSample->listentry); if (list_empty(&This->used_list) && This->bDecommitQueued && This->bCommitted) { HRESULT hrfree; if (This->lWaiting != 0) ERR("Waiting: %d\n", This->lWaiting); This->bCommitted = FALSE; This->bDecommitQueued = FALSE; CloseHandle(This->hSemWaiting); This->hSemWaiting = NULL; if (FAILED(hrfree = This->fnFree(iface))) ERR("fnFree failed with error 0x%x\n", hrfree); } } LeaveCriticalSection(This->pCritSect); /* notify a waiting thread that there is now a free buffer */ if (This->hSemWaiting && !ReleaseSemaphore(This->hSemWaiting, 1, NULL)) { ERR("ReleaseSemaphore failed with error %u\n", GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError()); } return hr; }
static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface) { BaseMemAllocator *This = (BaseMemAllocator *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() Release from %ld\n", iface, ref + 1); if (!ref) { CloseHandle(This->hSemWaiting); if (This->bCommitted) This->fnFree(iface); HeapFree(GetProcessHeap(), 0, This->pProps); CoTaskMemFree(This); return 0; } return ref; }
static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface) { BaseMemAllocator *This = impl_from_IMemAllocator(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() Release from %d\n", iface, ref + 1); if (!ref) { CloseHandle(This->hSemWaiting); if (This->bCommitted) This->fnFree(iface); This->fnDestroyed(iface); return 0; } return ref; }
static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface) { BaseMemAllocator *This = (BaseMemAllocator *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() Release from %d\n", iface, ref + 1); if (!ref) { CloseHandle(This->hSemWaiting); if (This->bCommitted) This->fnFree(iface); CoTaskMemFree(This->pProps); This->csState.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->csState); CoTaskMemFree(This); return 0; } return ref; }
static HRESULT WINAPI BaseMemAllocator_Decommit(IMemAllocator * iface) { BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr; TRACE("(%p)->()\n", This); EnterCriticalSection(This->pCritSect); { if (!This->bCommitted) hr = S_OK; else { if (!list_empty(&This->used_list)) { This->bDecommitQueued = TRUE; /* notify ALL waiting threads that they cannot be allocated a buffer any more */ ReleaseSemaphore(This->hSemWaiting, This->lWaiting, NULL); hr = S_OK; } else { if (This->lWaiting != 0) ERR("Waiting: %d\n", This->lWaiting); This->bCommitted = FALSE; CloseHandle(This->hSemWaiting); This->hSemWaiting = NULL; hr = This->fnFree(iface); if (FAILED(hr)) ERR("fnFree failed with error 0x%x\n", hr); } } } LeaveCriticalSection(This->pCritSect); return hr; }