blob: 858b5b7160d38d031a53f553c17c67d385075b06 [file]
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#include "clockable.hpp"
#include <vfwmsgs.h>
#include <cassert>
CLockable::CLockable() :
m_hMutex(0)
{
}
CLockable::~CLockable()
{
Final();
}
HRESULT CLockable::Init()
{
if (m_hMutex) //weird
return S_FALSE;
m_hMutex = CreateMutex(0, 0, 0);
if (m_hMutex)
return S_OK;
const DWORD e = GetLastError();
return HRESULT_FROM_WIN32(e);
}
HRESULT CLockable::Final()
{
if (m_hMutex == 0)
return S_FALSE;
const BOOL b = CloseHandle(m_hMutex);
m_hMutex = 0;
if (b)
return S_OK;
const DWORD e = GetLastError();
return HRESULT_FROM_WIN32(e);
}
HRESULT CLockable::Seize(DWORD timeout_ms)
{
if (m_hMutex == 0)
return VFW_E_WRONG_STATE;
DWORD index;
const HRESULT hr = CoWaitForMultipleHandles(
0, //wait flags
timeout_ms,
1,
&m_hMutex,
&index);
//despite the "S" in this name, this is an error
if (hr == RPC_S_CALLPENDING)
return VFW_E_TIMEOUT;
if (FAILED(hr))
return hr;
assert(index == 0);
return S_OK;
}
HRESULT CLockable::Release()
{
if (m_hMutex == 0)
return VFW_E_WRONG_STATE;
const BOOL b = ReleaseMutex(m_hMutex);
if (b)
return S_OK;
const DWORD e = GetLastError();
return HRESULT_FROM_WIN32(e);
}
CLockable::Lock::Lock() :
m_pLockable(0)
{
}
CLockable::Lock::~Lock()
{
Release();
}
HRESULT CLockable::Lock::Seize(CLockable* pLockable)
{
if (pLockable == 0)
return E_INVALIDARG;
if (m_pLockable)
return VFW_E_WRONG_STATE;
const HRESULT hr = pLockable->Seize(5000);
if (FAILED(hr))
return hr;
m_pLockable = pLockable;
return S_OK;
}
HRESULT CLockable::Lock::Release()
{
if (m_pLockable == 0)
return S_FALSE;
const HRESULT hr = m_pLockable->Release();
m_pLockable = 0;
return hr;
}