Example #1
0
TEST_F(FSEventsTests, test_fsevents_event_action) {
  // Assume event type is registered.
  StartEventLoop();

  // Simulate registering an event subscriber.
  auto sub = std::make_shared<TestFSEventsEventSubscriber>();
  auto status = sub->init();

  auto sc = sub->GetSubscription(real_test_path, 0);
  EventFactory::registerEventSubscriber(sub);

  sub->subscribe(&TestFSEventsEventSubscriber::Callback, sc);
  event_pub_->configure();

  CreateEvents();
  sub->WaitForEvents(kMaxEventLatency, 1);

  // Make sure the fsevents action was expected.
  ASSERT_TRUE(sub->actions_.size() > 0);
  bool has_created = false;
  bool has_unknown = false;
  {
    WriteLock lock(sub->mutex_);
    for (const auto& action : sub->actions_) {
      // Expect either a created event or attributes modified event.
      if (action == "CREATED" || action == "ATTRIBUTES_MODIFIED") {
        has_created = true;
      } else if (action == "UNKNOWN" || action == "") {
        // Allow an undetermined but existing FSevent on our target to pass.
        has_unknown = true;
      }
    }
  }
  EXPECT_TRUE(has_created || has_unknown);

  CreateEvents();
  sub->WaitForEvents(kMaxEventLatency, 2);
  bool has_updated = false;
  {
    WriteLock lock(sub->mutex_);
    // We may have triggered several updated events.
    for (const auto& action : sub->actions_) {
      if (action == "UPDATED") {
        has_updated = true;
      }
    }
  }
  EXPECT_TRUE(has_updated);

  EndEventLoop();
}
Example #2
0
TEST_F(INotifyTests, test_inotify_run) {
  // Assume event type is registered.
  event_pub_ = std::make_shared<INotifyEventPublisher>();
  auto status = EventFactory::registerEventPublisher(event_pub_);
  EXPECT_TRUE(status.ok());

  // Create a temporary file to watch, open writeable
  FILE* fd = fopen(kRealTestPath.c_str(), "w");

  // Create a subscriber.
  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  EventFactory::registerEventSubscriber(sub);

  // Create a subscriptioning context
  auto mc = std::make_shared<INotifySubscriptionContext>();
  mc->path = kRealTestPath;
  status = EventFactory::addSubscription(
      "inotify", Subscription::create("TestINotifyEventSubscriber", mc));
  EXPECT_TRUE(status.ok());

  // Create an event loop thread (similar to main)
  boost::thread temp_thread(EventFactory::run, "inotify");
  EXPECT_TRUE(event_pub_->numEvents() == 0);

  // Cause an inotify event by writing to the watched path.
  fputs("inotify", fd);
  fclose(fd);

  // Wait for the thread's run loop to select.
  WaitForEvents(kMaxEventLatency);
  EXPECT_TRUE(event_pub_->numEvents() > 0);
  EventFactory::end();
  temp_thread.join();
}
Example #3
0
TEST_F(FSEventsTests, test_fsevents_run) {
  // Assume event type is registered.
  event_pub_ = std::make_shared<FSEventsEventPublisher>();
  EventFactory::registerEventPublisher(event_pub_);

  // Create a subscriber.
  auto sub = std::make_shared<TestFSEventsEventSubscriber>();
  EventFactory::registerEventSubscriber(sub);

  // Create a subscriptioning context
  auto mc = std::make_shared<FSEventsSubscriptionContext>();
  mc->path = real_test_path;
  EventFactory::addSubscription(
      "fsevents", Subscription::create("TestFSEventsEventSubscriber", mc));
  event_pub_->configure();

  // Create an event loop thread (similar to main)
  temp_thread_ = std::thread(EventFactory::run, "fsevents");
  EXPECT_TRUE(event_pub_->numEvents() == 0);

  // Wait for the thread to start and the FSEvents stream to turn on.
  WaitForStream(kMaxEventLatency);

  // Cause an fsevents event(s) by writing to the watched path.
  CreateEvents();

  // Wait for the thread's run loop to select.
  WaitForEvents(kMaxEventLatency);

  EXPECT_TRUE(event_pub_->numEvents() > 0);

  // We are managing the thread ourselves, so no join needed.
  EventFactory::end(false);
  temp_thread_.join();
}
// Get the next sample in the queue. If there is none, wait for at most
// dwTimeout milliseconds for one to become available before failing.
// Returns: S_FALSE if no sample available
// Threading: only one thread should be calling GetNextSampleOrCommand()
// but it can be different from the one calling PutSample()/PutCommand()
HRESULT CQueuedAudioSink::GetNextSampleOrCommand(AudioSinkCommand* pCommand, IMediaSample** pSample, DWORD dwTimeout,
                                                  vector<HANDLE>* pHandles, vector<DWORD>* pWaitObjects, bool handleOOBOnly)
{
  HRESULT hr = WaitForEvents(dwTimeout, pHandles, pWaitObjects);

  if (hr == MPAR_S_WAIT_TIMED_OUT || hr == S_FALSE)
  {
    if (pSample && *pSample && !handleOOBOnly)
    {
      (*pSample)->Release();
      (*pSample) = NULL;
    }

    *pCommand = ASC_Nop;
    return WAIT_TIMEOUT;
  }
  
  {
    CAutoLock OOBQueueLock(&m_OOBInputQueueLock);
    if (!m_OOBInputQueue.empty())
    {
      TQueueEntry entry = m_OOBInputQueue.front();
      if (pCommand)
        *pCommand = entry.Command;
      
      m_OOBInputQueue.pop();

      if (m_OOBInputQueue.empty())
        ResetEvent(m_hOOBCommandAvailableEvent);

      return S_OK;
    }
    else if (handleOOBOnly)
    {
      *pCommand = ASC_Nop;
      return S_OK;
    }
  }

  if (hr != S_OK)
    return hr;

  if (pSample && *pSample)
    (*pSample)->Release();

  CAutoLock queueLock(&m_inputQueueLock);
  TQueueEntry entry = m_inputQueue.front();
  if (pSample)
    *pSample = entry.Sample.Detach();
  if (pCommand)
    *pCommand = entry.Command;

  m_inputQueue.erase(m_inputQueue.begin());
  if (m_inputQueue.empty())
    ResetEvent(m_hInputAvailableEvent);
  //if (m_InputQueue.empty())
  //  SetEvent(m_hInputQueueEmptyEvent);

  return S_OK;
}
TEST_F(FSEventsTests, test_fsevents_run) {
  // Assume event type is registered.
  event_pub_ = std::make_shared<FSEventsEventPublisher>();
  EventFactory::registerEventPublisher(event_pub_);

  // Create a subscriber.
  auto sub = std::make_shared<TestFSEventsEventSubscriber>();
  EventFactory::registerEventSubscriber(sub);

  // Create a subscriptioning context
  auto mc = std::make_shared<FSEventsSubscriptionContext>();
  mc->path = kRealTestPath;
  EventFactory::addSubscription("fsevents", Subscription::create("TestFSEventsEventSubscriber", mc));

  // Create an event loop thread (similar to main)
  boost::thread temp_thread(EventFactory::run, "fsevents");
  EXPECT_TRUE(event_pub_->numEvents() == 0);

  // Cause an fsevents event(s) by writing to the watched path.
  CreateEvents();

  // Wait for the thread's run loop to select.
  WaitForEvents(kMaxEventLatency);

  EXPECT_TRUE(event_pub_->numEvents() > 0);
  EventFactory::end();
}
void HandleSet::HandleEvents(Reactor *reactor, LeaderFollowerPool *lfp, long timeout) {
	StartTrace(HandleSet.HandleEvents);

	Acceptor *acceptor = WaitForEvents(timeout);
	if (acceptor) {
		reactor->ProcessEvent(acceptor->DoAccept(), lfp);
	} else {
		// timeout case
		lfp->PromoteNewLeader();
	}
}
Example #7
0
TEST_F(INotifyTests, test_inotify_fire_event) {
  // Assume event type is registered.
  StartEventLoop();
  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  sub->init();

  // Create a subscriptioning context, note the added Event to the symbol
  auto sc = sub->GetSubscription(kRealTestPath, 0);
  sub->subscribe(&TestINotifyEventSubscriber::SimpleCallback, sc, nullptr);

  TriggerEvent(kRealTestPath);
  sub->WaitForEvents(kMaxEventLatency);

  // Make sure our expected event fired (aka subscription callback was called).
  EXPECT_TRUE(sub->count() > 0);
  StopEventLoop();
}
Example #8
0
TEST_F(INotifyTests, test_inotify_event_action) {
  // Assume event type is registered.
  StartEventLoop();
  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  sub->init();

  auto sc = sub->GetSubscription(kRealTestPath, 0);
  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc, nullptr);

  TriggerEvent(kRealTestPath);
  sub->WaitForEvents(kMaxEventLatency, 4);

  // Make sure the inotify action was expected.
  EXPECT_EQ(sub->actions().size(), 4);
  EXPECT_EQ(sub->actions()[0], "UPDATED");
  EXPECT_EQ(sub->actions()[1], "OPENED");
  EXPECT_EQ(sub->actions()[2], "UPDATED");
  EXPECT_EQ(sub->actions()[3], "UPDATED");
  StopEventLoop();
}
Example #9
0
TEST_F(FSEventsTests, test_fsevents_fire_event) {
  // Assume event type is registered.
  StartEventLoop();

  // Simulate registering an event subscriber.
  auto sub = std::make_shared<TestFSEventsEventSubscriber>();
  auto status = sub->init();

  // Create a subscriptioning context, note the added Event to the symbol
  auto sc = sub->GetSubscription(0);
  sub->subscribe(&TestFSEventsEventSubscriber::SimpleCallback, sc, nullptr);
  CreateEvents();

  // This time wait for the callback.
  sub->WaitForEvents(kMaxEventLatency, 1);

  // Make sure our expected event fired (aka subscription callback was called).
  EXPECT_TRUE(sub->callback_count_ > 0);
  EndEventLoop();
}
Example #10
0
TEST_F(INotifyTests, test_inotify_event_action) {
  // Assume event type is registered.
  StartEventLoop();
  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  EventFactory::registerEventSubscriber(sub);

  auto sc = sub->GetSubscription(real_test_path, 0);
  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc, nullptr);

  TriggerEvent(real_test_path);
  sub->WaitForEvents(kMaxEventLatency, 3);

  // Make sure the inotify action was expected.
  EXPECT_GT(sub->actions().size(), 0U);
  if (sub->actions().size() >= 2) {
    EXPECT_EQ(sub->actions()[0], "UPDATED");
    EXPECT_EQ(sub->actions()[1], "UPDATED");
  }
  StopEventLoop();
}
Example #11
0
TEST_F(FSEventsTests, test_fsevents_event_action) {
  // Assume event type is registered.
  StartEventLoop();

  // Simulate registering an event subscriber.
  auto sub = std::make_shared<TestFSEventsEventSubscriber>();
  auto status = sub->init();

  auto sc = sub->GetSubscription(0);
  EventFactory::registerEventSubscriber(sub);
  sub->subscribe(&TestFSEventsEventSubscriber::Callback, sc, nullptr);
  CreateEvents();
  sub->WaitForEvents(kMaxEventLatency);

  // Make sure the fsevents action was expected.
  EXPECT_TRUE(sub->actions_.size() > 0);
  if (sub->actions_.size() > 1) {
    EXPECT_EQ(sub->actions_[0], "UPDATED");
  }
  EndEventLoop();
}
Example #12
0
TEST_F(INotifyTests, test_inotify_recursion) {
  StartEventLoop();

  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  sub->init();

  boost::filesystem::create_directory(kRealTestDir);
  boost::filesystem::create_directory(kRealTestSubDir);

  // Subscribe to the directory inode
  auto mc = sub->createSubscriptionContext();
  mc->path = kRealTestDir;
  mc->recursive = true;
  sub->subscribe(&TestINotifyEventSubscriber::Callback, mc, nullptr);

  // Trigger on a subdirectory's file.
  TriggerEvent(kRealTestSubDirPath);

  sub->WaitForEvents(kMaxEventLatency, 1);
  EXPECT_TRUE(sub->count() > 0);
  StopEventLoop();
}
Example #13
0
TEST_F(INotifyTests, test_inotify_directory_watch) {
  StartEventLoop();

  auto sub = std::make_shared<TestINotifyEventSubscriber>();
  EventFactory::registerEventSubscriber(sub);

  fs::create_directory(real_test_dir);
  fs::create_directory(real_test_sub_dir);

  // Subscribe to the directory inode
  auto mc = sub->createSubscriptionContext();
  mc->path = real_test_dir;
  mc->recursive = true;
  sub->subscribe(&TestINotifyEventSubscriber::Callback, mc, nullptr);

  // Trigger on a subdirectory's file.
  TriggerEvent(real_test_sub_dir_path);

  sub->WaitForEvents(kMaxEventLatency, 1);
  EXPECT_TRUE(sub->count() > 0);
  StopEventLoop();
}
Example #14
0
void CL::waitForEvent(const std::vector<cl::Event> &events) {
	if(events.size() == 0)
		return;
	cl_int err = WaitForEvents(events);
	CL::check_error(err, "Wait for events");
}
DWORD CWASAPIRenderFilter::ThreadProc()
{
  Log("CWASAPIRenderFilter::Render thread - starting up - thread ID: %d", m_ThreadId);
  
  SetThreadName(0, "WASAPI-renderer");

  // Polling delay
  LARGE_INTEGER liDueTime; 
  liDueTime.QuadPart = -1LL;

  AudioSinkCommand command;
  
  LONGLONG writeSilence = 0;
  BYTE* sampleData = NULL;

  bool flush = false;
  bool sampleProcessed = false;

  REFERENCE_TIME dueTime = 0;
  REFERENCE_TIME maxSampleWaitTime = Latency() / 20000;

  HRESULT hr = S_FALSE;

  m_csResources.Lock();

  if (m_pSettings->m_bReleaseDeviceOnStop && !m_pAudioClient && m_pInputFormat)
  {
    hr = CreateAudioClient(true);
    if (FAILED(hr))
    {
      Log("CWASAPIRenderFilter::Render thread Error, audio client not available: (0x%08x)", hr);
      StopRenderThread();
      m_csResources.Unlock();
      return 0;
    }
  }

  if (m_pAudioClient)
  {
    hr = StartAudioClient();
    if (FAILED(hr))
    {
      Log("CWASAPIRenderFilter::Render thread Error, starting audio client failed: (0x%08x)", hr);
      StopRenderThread();
      m_csResources.Unlock();
      return 0;
    }
  }

  if (!m_bDeviceInitialized)
  {
    Log("CWASAPIRenderFilter::Render thread Error, device not initialized");
    StopRenderThread();
    m_csResources.Unlock();
    return 0;
  }

  EnableMMCSS();
  m_state = StateRunning;

  while (true)
  {
    if (flush)
    {
      Log("CWASAPIRenderFilter::Render thread flushing buffers");
      HandleFlush();
      flush = false;
    }
    
    m_csResources.Unlock();
    hr = WaitForEvents(INFINITE, &m_hDataEvents, &m_dwDataWaitObjects);
    m_csResources.Lock();

    if (hr == MPAR_S_THREAD_STOPPING || !m_pAudioClient)
    {
      StopRenderThread();
      return 0;
    }
    else if (hr == MPAR_S_NEED_DATA)
    {
      UpdateAudioClock();

      UINT32 bytesFilled = 0;
      UINT32 bufferSize = 0;
      UINT32 currentPadding = 0;
      UINT32 bufferSizeInBytes = 0;
      BYTE* data = NULL;
      DWORD flags = 0;

      static BYTE* prevData = NULL;
       
      hr = GetWASAPIBuffer(bufferSize, currentPadding, bufferSizeInBytes, &data);
      if (SUCCEEDED(hr))
      {
        do
        {
          fetchSample:

          bool OOBCommandOnly = m_nDataLeftInSample > 0;

          if (m_nDataLeftInSample == 0 || OOBCommandOnly)
          {
            m_csResources.Unlock();
            HRESULT result = GetNextSampleOrCommand(&command, &m_pCurrentSample.p, maxSampleWaitTime, &m_hSampleEvents,
                                                    &m_dwSampleWaitObjects, OOBCommandOnly);
            m_csResources.Lock();

            if (result == MPAR_S_THREAD_STOPPING || !m_pAudioClient)
            {
              if (m_pAudioClient)
              {
                hr = m_pRenderClient->ReleaseBuffer(bufferSize - currentPadding, flags);
                if (FAILED(hr) && hr != AUDCLNT_E_OUT_OF_ORDER)
                  Log("CWASAPIRenderFilter::Render thread: ReleaseBuffer failed (0x%08x)", hr);
              }

              StopRenderThread();
              return 0;
            }

            if (!m_pCurrentSample)
              m_nDataLeftInSample = 0;
              
            if (command == ASC_PutSample && m_pCurrentSample)
            {
              sampleProcessed = false;
              m_nSampleOffset = 0;
              m_nDataLeftInSample = m_pCurrentSample->GetActualDataLength();
            }
            else if (command == ASC_Flush)
            {
              m_pCurrentSample.Release();

              flush = true;
              sampleData = NULL;
              m_nSampleOffset = 0;
              m_nDataLeftInSample = 0;

              break;
            }
            else if (command == ASC_Pause)
            {
              m_pCurrentSample.Release();
              m_state = StatePaused;
            }
            else if (command == ASC_Resume)
            {
              sampleProcessed = false;
              writeSilence = 0;
              m_state = StateRunning;
              if (!m_pCurrentSample)
              {
                m_nDataLeftInSample = 0;
                goto fetchSample;
              }
            }
          }

          if (m_state != StateRunning)
            writeSilence = bufferSizeInBytes - bytesFilled;
          else if (m_nSampleOffset == 0 && !OOBCommandOnly)
          {
            // TODO error checking
            if (CheckSample(m_pCurrentSample, bufferSize - currentPadding) == S_FALSE)
            {
              GetWASAPIBuffer(bufferSize, currentPadding, bufferSizeInBytes, &data);
              bytesFilled = 0;
            }
          }

          if (writeSilence == 0 && (m_nSampleOffset == 0 || m_nSampleNum == 0) && !sampleProcessed)
          {
            HRESULT schedulingHR = CheckStreamTimeline(m_pCurrentSample, &dueTime, m_nSampleOffset);
            sampleProcessed = true;
              
            // m_pCurrentSample must exist if CheckStreamTimeline returns either of these
            if (schedulingHR == MPAR_S_DROP_SAMPLE)
            {
              m_pCurrentSample.Release();
              m_nDataLeftInSample = 0;
              goto fetchSample;
            }
            else if (schedulingHR == MPAR_S_WAIT_RENDER_TIME)
              CalculateSilence(&dueTime, &writeSilence);
          }

          if (writeSilence == 0 && m_pCurrentSample)
            RenderAudio(data, bufferSizeInBytes, m_nDataLeftInSample, m_nSampleOffset, m_pCurrentSample, bytesFilled);
          else
          {
            if (bufferSizeInBytes == writeSilence)
              flags = AUDCLNT_BUFFERFLAGS_SILENT;

            if (!m_pCurrentSample)
              writeSilence = bufferSizeInBytes;

            RenderSilence(data, bufferSizeInBytes, writeSilence, bytesFilled);
          }
        } while (bytesFilled < bufferSizeInBytes);

        hr = m_pRenderClient->ReleaseBuffer(bufferSize - currentPadding, flags);

        if (FAILED(hr) && hr != AUDCLNT_E_OUT_OF_ORDER)
          Log("CWASAPIRenderFilter::Render thread: ReleaseBuffer failed (0x%08x)", hr);
      }

      if (!m_pSettings->m_bWASAPIUseEventMode)
      {
        if (m_pAudioClient)
          hr = m_pAudioClient->GetCurrentPadding(&currentPadding);
        else
          hr = S_FALSE;

        if (SUCCEEDED(hr) && bufferSize > 0)
        {
          liDueTime.QuadPart = (double)currentPadding / (double)bufferSize * (double)m_pSettings->m_hnsPeriod * -0.9;
          // Log(" currentPadding: %d QuadPart: %lld", currentPadding, liDueTime.QuadPart);
        }
        else
        {
          liDueTime.QuadPart = (double)m_pSettings->m_hnsPeriod * -0.9;
          if (hr != AUDCLNT_E_NOT_INITIALIZED)
            Log("CWASAPIRenderFilter::Render thread: GetCurrentPadding failed (0x%08x)", hr);  
        }
        SetWaitableTimer(m_hDataEvent, &liDueTime, 0, NULL, NULL, 0);
      }
    }
  }
  
  m_csResources.Unlock();
  return 0;
}