RefPtr<MediaDecoderReader::MetadataPromise>
MediaDecoderReader::AsyncReadMetadata()
{
  MOZ_ASSERT(OnTaskQueue());
  DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");

  // Attempt to read the metadata.
  MetadataHolder metadata;
  metadata.mInfo = MakeUnique<MediaInfo>();
  MetadataTags* tags = nullptr;
  nsresult rv = ReadMetadata(metadata.mInfo.get(), &tags);
  metadata.mTags.reset(tags);
  metadata.mInfo->AssertValid();

  // Update the buffer ranges before resolving the metadata promise. Bug 1320258.
  UpdateBuffered();

  // We're not waiting for anything. If we didn't get the metadata, that's an
  // error.
  if (NS_FAILED(rv) || !metadata.mInfo->HasValidMedia()) {
    DECODER_WARN("ReadMetadata failed, rv=%" PRIx32 " HasValidMedia=%d",
                 static_cast<uint32_t>(rv), metadata.mInfo->HasValidMedia());
    return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
  }

  // Success!
  return MetadataPromise::CreateAndResolve(Move(metadata), __func__);
}
void InputHandler_DInput::Update(float fDeltaTime)
{
	RageTimer zero;
	zero.SetZero();

	/* Handle polled devices. */
	PollAndAcquireDevices();
	for( unsigned i = 0; i < Devices.size(); ++i )
	{
		if( !Devices[i].buffered )
			UpdatePolled( Devices[i], zero );
		else if( !InputThread.IsCreated() )
		{
			/* If we have an input thread, it'll handle buffered devices. */
			UpdateBuffered( Devices[i], zero );
		}
	}

	InputHandler::UpdateTimer();
}
    void Update()
    {
        //ZDebugOutput("Mouse Update\n");

        if (m_bEnabled) {
            //ZDebugOutput("Mouse Enabled\n");
            HRESULT hr = m_pdid->Acquire();

            //
            // We have to handle the case where another app has captured the
            // mouse, since we may have been switched out.
            //

            if (hr != DIERR_OTHERAPPHASPRIO) {
                DDCall(hr);

                if (m_bBuffered) {
                    UpdateBuffered();
                } else {
                    UpdatePolled();
                }
            }
        }
    }
void InputHandler_DInput::InputThreadMain()
{
	if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST))
		LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set DirectInput thread priority"));

	/* Enable priority boosting. */
	SetThreadPriorityBoost( GetCurrentThread(), FALSE );

	vector<DIDevice*> BufferedDevices, UnbufferedDevices;
	HANDLE Handle = CreateEvent(NULL, FALSE, FALSE, NULL);
	for( unsigned i = 0; i < Devices.size(); ++i )
	{
		if( !Devices[i].buffered )
		{
			UnbufferedDevices.push_back( &Devices[i] );
			continue;
		}
        
		BufferedDevices.push_back( &Devices[i] );

		IDirectInputDevice2_Unacquire(Devices[i].Device);
		HRESULT hr = IDirectInputDevice2_SetEventNotification(Devices[i].Device, Handle);
		if( FAILED(hr) )
			LOG->Warn("IDirectInputDevice2_SetEventNotification failed on %i", i);
		IDirectInputDevice2_Acquire(Devices[i].Device);
	}

	while(!shutdown)
	{
		m_DebugTimer.StartUpdate();
		CHECKPOINT;
		if( BufferedDevices.size() )
		{
			/* Update buffered devices. */
			PollAndAcquireDevices();

			int ret = WaitForSingleObjectEx( Handle, 50, true );
			if( ret == -1 )
			{
				LOG->Trace( werr_ssprintf(GetLastError(), "WaitForSingleObjectEx failed") );
				continue;
			}

			if( ret == WAIT_OBJECT_0 )
			{
				RageTimer now;
				for( unsigned i = 0; i < BufferedDevices.size(); ++i )
					UpdateBuffered( *BufferedDevices[i], now );
			}
		}
		CHECKPOINT;

		/* If we have no buffered devices, we didn't delay at WaitForMultipleObjectsEx. */
		if( BufferedDevices.size() == 0 )
			usleep( 50000 );
		CHECKPOINT;

		m_DebugTimer.EndUpdate();
	}
	CHECKPOINT;

	for( unsigned i = 0; i < Devices.size(); ++i )
	{
		if( !Devices[i].buffered )
			continue;

		IDirectInputDevice2_Unacquire(Devices[i].Device);
        IDirectInputDevice2_SetEventNotification( Devices[i].Device, NULL );
	}

	CloseHandle(Handle);
}