Exemplo n.º 1
0
DeviceBase* DeviceHandle::CreateDevice()
{       
    if (!pImpl)
        return 0;
    
    DeviceBase*            device = 0;
    Ptr<DeviceManagerImpl> manager= 0;

    // Since both manager and device pointers can only be destroyed during a lock,
    // hold it while checking for availability.
    // AddRef to manager so that it doesn't get released on us.
    {
        Lock::Locker deviceLockScope(pImpl->GetLock());

        if (pImpl->pDevice)
        {
            pImpl->pDevice->AddRef();
            return device;
        }
        manager = pImpl->GetManagerImpl();
    }

    if (manager)
    {
        // Queue up a CreateDevice request. This fills in '&device' with AddRefed value,
        // or keep it at null.
        manager->GetThreadQueue()->PushCallAndWaitResult(
            manager.GetPtr(), &DeviceManagerImpl::CreateDevice_MgrThread,
                              &device, pImpl, (DeviceBase*)0);
    }
    return device;
}
void DeviceCreateDesc::Release()
{
    while(1)
    {
        UInt32 handleCount = HandleCount;
        // HandleCount must obviously be >= 1, since we are releasing it.
        OVR_ASSERT(handleCount > 0);

        // {1 -> 0} transition may cause us to be destroyed, so require a lock.
        if (handleCount == 1)
        {       
            Ptr<DeviceManagerLock>  lockKeepAlive;
            Lock::Locker            deviceLockScope(GetLock());

            if (!HandleCount.CompareAndSet_NoSync(handleCount, 0))
                continue;
            
            OVR_ASSERT(pDevice == 0);

            // Destroy *this if the manager was destroyed already, or Enumerated
            // is false (device no longer available).           
            if (!GetManagerImpl() || !Enumerated)
            {
                lockKeepAlive = pLock;

                // Remove from manager list (only matters for !Enumerated).
                if (pNext)
                {
                    RemoveNode();
                    pNext = pPrev = 0;
                }

                delete this;
            }

            // Available DeviceCreateDesc may survive with { HandleCount == 0 },
            // in case it might be enumerated again later.
            break;
        }
        else if (HandleCount.CompareAndSet_NoSync(handleCount, handleCount-1))
        {
            break;
        }
    }
}