コード例 #1
0
void CacheIOThread::LoopOneLevel(uint32_t aLevel)
{
    eventtracer::AutoEventTracer tracer(this, eventtracer::eExec, eventtracer::eDone,
                                        sLevelTraceName[aLevel]);

    nsTArray<nsRefPtr<nsIRunnable> > events;
    events.SwapElements(mEventQueue[aLevel]);
    uint32_t length = events.Length();

    bool returnEvents = false;
    uint32_t index;
    {
        MonitorAutoUnlock unlock(mMonitor);

        for (index = 0; index < length; ++index) {
            if (EventsPending(aLevel)) {
                // Somebody scheduled a new event on a lower level, break and harry
                // to execute it!  Don't forget to return what we haven't exec.
                returnEvents = true;
                break;
            }

            events[index]->Run();
            events[index] = nullptr;
        }
    }

    if (returnEvents)
        mEventQueue[aLevel].InsertElementsAt(0, events.Elements() + index, length - index);
}
コード例 #2
0
void CacheIOThread::LoopOneLevel(uint32_t aLevel)
{
  EventQueue events;
  events.SwapElements(mEventQueue[aLevel]);
  EventQueue::size_type length = events.Length();

  mCurrentlyExecutingLevel = aLevel;

  bool returnEvents = false;
  bool reportTelementry = true;

  EventQueue::size_type index;
  {
    MonitorAutoUnlock unlock(mMonitor);

    for (index = 0; index < length; ++index) {
      if (EventsPending(aLevel)) {
        // Somebody scheduled a new event on a lower level, break and harry
        // to execute it!  Don't forget to return what we haven't exec.
        returnEvents = true;
        break;
      }

      if (reportTelementry) {
        reportTelementry = false;
        CacheIOTelemetry::Report(aLevel, length);
      }

      // Drop any previous flagging, only an event on the current level may set
      // this flag.
      mRerunCurrentEvent = false;

      events[index]->Run();

      if (mRerunCurrentEvent) {
        // The event handler yields to higher priority events and wants to rerun.
        returnEvents = true;
        break;
      }

      // Release outside the lock.
      events[index] = nullptr;
    }
  }

  if (returnEvents)
    mEventQueue[aLevel].InsertElementsAt(0, events.Elements() + index, length - index);
}
コード例 #3
0
void CacheIOThread::LoopOneLevel(uint32_t aLevel)
{
    eventtracer::AutoEventTracer tracer(this, eventtracer::eExec, eventtracer::eDone,
                                        sLevelTraceName[aLevel]);

    nsTArray<nsRefPtr<nsIRunnable> > events;
    events.SwapElements(mEventQueue[aLevel]);
    uint32_t length = events.Length();

    mCurrentlyExecutingLevel = aLevel;

    bool returnEvents = false;
    uint32_t index;
    {
        MonitorAutoUnlock unlock(mMonitor);

        for (index = 0; index < length; ++index) {
            if (EventsPending(aLevel)) {
                // Somebody scheduled a new event on a lower level, break and harry
                // to execute it!  Don't forget to return what we haven't exec.
                returnEvents = true;
                break;
            }

            // Drop any previous flagging, only an event on the current level may set
            // this flag.
            mRerunCurrentEvent = false;

            events[index]->Run();

            if (mRerunCurrentEvent) {
                // The event handler yields to higher priority events and wants to rerun.
                returnEvents = true;
                break;
            }

            // Release outside the lock.
            events[index] = nullptr;
        }
    }

    if (returnEvents)
        mEventQueue[aLevel].InsertElementsAt(0, events.Elements() + index, length - index);
}
コード例 #4
0
bool CacheIOThread::YieldInternal()
{
  if (!IsCurrentThread()) {
    NS_WARNING("Trying to yield to priority events on non-cache2 I/O thread? "
               "You probably do something wrong.");
    return false;
  }

  if (mCurrentlyExecutingLevel == XPCOM_LEVEL) {
    // Doesn't make any sense, since this handler is the one
    // that would be executed as the next one.
    return false;
  }

  if (!EventsPending(mCurrentlyExecutingLevel))
    return false;

  mRerunCurrentEvent = true;
  return true;
}
コード例 #5
0
void CacheIOThread::ThreadFunc()
{
  nsCOMPtr<nsIThreadInternal> threadInternal;

  {
    MonitorAutoLock lock(mMonitor);

    // This creates nsThread for this PRThread
    nsCOMPtr<nsIThread> xpcomThread = NS_GetCurrentThread();

    threadInternal = do_QueryInterface(xpcomThread);
    if (threadInternal)
      threadInternal->SetObserver(this);

    mXPCOMThread = xpcomThread.forget().take();

    lock.NotifyAll();

    do {
loopStart:
      // Reset the lowest level now, so that we can detect a new event on
      // a lower level (i.e. higher priority) has been scheduled while
      // executing any previously scheduled event.
      mLowestLevelWaiting = LAST_LEVEL;

      // Process xpcom events first
      while (mHasXPCOMEvents) {
        mHasXPCOMEvents = false;
        mCurrentlyExecutingLevel = XPCOM_LEVEL;

        MonitorAutoUnlock unlock(mMonitor);

        bool processedEvent;
        nsresult rv;
        do {
          nsIThread *thread = mXPCOMThread;
          rv = thread->ProcessNextEvent(false, &processedEvent);
        } while (NS_SUCCEEDED(rv) && processedEvent);
      }

      uint32_t level;
      for (level = 0; level < LAST_LEVEL; ++level) {
        if (!mEventQueue[level].Length()) {
          // no events on this level, go to the next level
          continue;
        }

        LoopOneLevel(level);

        // Go to the first (lowest) level again
        goto loopStart;
      }

      if (EventsPending())
        continue;

      if (mShutdown)
        break;

      lock.Wait(PR_INTERVAL_NO_TIMEOUT);

      if (EventsPending())
        continue;

    } while (true);

    MOZ_ASSERT(!EventsPending());

    // This is for correct assertion on XPCOM events dispatch.
    mInsideLoop = false;
  } // lock

  if (threadInternal)
    threadInternal->SetObserver(nullptr);
}
コード例 #6
0
ファイル: VP.c プロジェクト: berkus/nemesis
static bool_t EventsPending_m (VP_cl   *self )
{
    return VP$EventsPending(self);
}