Beispiel #1
0
size_t check_request_surprise() {
  auto& info = TI();
  auto& p = info.m_reqInjectionData;

  auto const flags = fetchAndClearSurpriseFlags();
  auto const do_timedout = (flags & TimedOutFlag) && !p.getDebuggerAttached();
  auto const do_memExceeded = flags & MemExceededFlag;
  auto const do_signaled = flags & SignaledFlag;
  auto const do_cpuTimedOut =
    (flags & CPUTimedOutFlag) && !p.getDebuggerAttached();
  auto const do_GC = flags & PendingGCFlag;

  // Start with any pending exception that might be on the thread.
  auto pendingException = info.m_pendingException;
  info.m_pendingException = nullptr;

  if (do_timedout) {
    p.setCPUTimeout(0);  // Stop CPU timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(TimedOutFlag);
    } else {
      pendingException = generate_request_timeout_exception();
    }
  }
  // Don't bother with the CPU timeout if we're already handling a wall timeout.
  if (do_cpuTimedOut && !do_timedout) {
    p.setTimeout(0);  // Stop wall timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(CPUTimedOutFlag);
    } else {
      pendingException = generate_request_cpu_timeout_exception();
    }
  }
  if (do_memExceeded) {
    if (pendingException) {
      setSurpriseFlag(MemExceededFlag);
    } else {
      pendingException = generate_memory_exceeded_exception();
    }
  }
  if (do_GC) {
    if (StickyFlags & PendingGCFlag) {
      clearSurpriseFlag(PendingGCFlag);
    }
    if (RuntimeOption::EvalEnableGC) {
      MM().collect("surprise");
    } else {
      MM().checkHeap("surprise");
    }
  }
  if (do_signaled) {
    HHVM_FN(pcntl_signal_dispatch)();
  }

  if (pendingException) {
    pendingException->throwException();
  }
  return flags;
}
Beispiel #2
0
ssize_t check_request_surprise(ThreadInfo* info) {
  auto& p = info->m_reqInjectionData;

  auto const flags = p.fetchAndClearFlags();
  bool do_timedout = (flags & RequestInjectionData::TimedOutFlag) &&
    !p.getDebuggerAttached();
  bool do_cpuTimedOut = (flags & RequestInjectionData::CPUTimedOutFlag) &&
    !p.getDebuggerAttached();
  bool do_memExceeded = (flags & RequestInjectionData::MemExceededFlag);
  bool do_signaled = (flags & RequestInjectionData::SignaledFlag);
  bool do_intervalTimer = (flags & RequestInjectionData::IntervalTimerFlag);

  // Start with any pending exception that might be on the thread.
  auto pendingException = info->m_pendingException;
  info->m_pendingException = nullptr;

  if (do_timedout) {
    p.setCPUTimeout(0);  // Stop CPU timer so we won't time out twice.
    if (pendingException) {
      p.setTimedOutFlag();
    } else {
      pendingException = generate_request_timeout_exception();
    }
  }
  // Don't bother with the CPU timeout if we're already handling a wall timeout.
  if (do_cpuTimedOut && !do_timedout) {
    p.setTimeout(0);  // Stop wall timer so we won't time out twice.
    if (pendingException) {
      p.setCPUTimedOutFlag();
    } else {
      pendingException = generate_request_cpu_timeout_exception();
    }
  }
  if (do_memExceeded) {
    if (pendingException) {
      p.setMemExceededFlag();
    } else {
      pendingException = generate_memory_exceeded_exception();
    }
  }
  if (do_signaled) {
    extern bool HHVM_FN(pcntl_signal_dispatch)();
    HHVM_FN(pcntl_signal_dispatch)();
  }
  if (do_intervalTimer) {
    IntervalTimer::RunCallbacks();
  }

  if (pendingException) {
    pendingException->throwException();
  }
  return flags;
}
Beispiel #3
0
size_t check_request_surprise() {
  auto& info = TI();
  auto& p = info.m_reqInjectionData;

  auto const flags = fetchAndClearSurpriseFlags();
  auto const do_timedout = (flags & TimedOutFlag) && !p.getDebuggerAttached();
  auto const do_memExceeded = flags & MemExceededFlag;
  auto const do_memThreshold = flags & MemThresholdFlag;
  auto const do_signaled = flags & SignaledFlag;
  auto const do_cpuTimedOut =
    (flags & CPUTimedOutFlag) && !p.getDebuggerAttached();
  auto const do_GC = flags & PendingGCFlag;

  // Start with any pending exception that might be on the thread.
  auto pendingException = info.m_pendingException;
  info.m_pendingException = nullptr;

  if (do_timedout) {
    p.setCPUTimeout(0);  // Stop CPU timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(TimedOutFlag);
    } else {
      pendingException = generate_request_timeout_exception();
    }
  }
  // Don't bother with the CPU timeout if we're already handling a wall timeout.
  if (do_cpuTimedOut && !do_timedout) {
    p.setTimeout(0);  // Stop wall timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(CPUTimedOutFlag);
    } else {
      pendingException = generate_request_cpu_timeout_exception();
    }
  }
  if (do_memExceeded) {
    if (pendingException) {
      setSurpriseFlag(MemExceededFlag);
    } else {
      pendingException = generate_memory_exceeded_exception();
    }
  }
  if (do_memThreshold) {
    clearSurpriseFlag(MemThresholdFlag);
    if (!g_context->m_memThresholdCallback.isNull()) {
      VMRegAnchor _;
      try {
        vm_call_user_func(g_context->m_memThresholdCallback, empty_array());
      } catch (Object& ex) {
        raise_error("Uncaught exception escaping mem Threshold callback: %s",
                    ex.toString().data());
      }
    }
  }
  if (do_GC) {
    VMRegAnchor _;
    if (RuntimeOption::EvalEnableGC) {
      MM().collect("surprise");
    } else {
      MM().checkHeap("surprise");
    }
  }
  if (do_signaled) {
    HHVM_FN(pcntl_signal_dispatch)();
  }

  if (pendingException) {
    pendingException->throwException();
  }
  return flags;
}
Beispiel #4
0
size_t handle_request_surprise(c_WaitableWaitHandle* wh, size_t mask) {
  auto& info = TI();
  auto& p = info.m_reqInjectionData;

  auto const flags = fetchAndClearSurpriseFlags() & mask;
  auto const debugging = p.getDebuggerAttached();

  // Start with any pending exception that might be on the thread.
  auto pendingException = info.m_pendingException;
  info.m_pendingException = nullptr;

  if ((flags & TimedOutFlag) && !debugging) {
    p.setCPUTimeout(0);  // Stop CPU timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(TimedOutFlag);
    } else {
      pendingException = generate_request_timeout_exception(wh);
    }
  } else if ((flags & CPUTimedOutFlag) && !debugging) {
    // Don't bother with the CPU timeout if we're already handling a wall
    // timeout.
    p.setTimeout(0);  // Stop wall timer so we won't time out twice.
    if (pendingException) {
      setSurpriseFlag(CPUTimedOutFlag);
    } else {
      pendingException = generate_request_cpu_timeout_exception(wh);
    }
  }
  if (flags & MemExceededFlag) {
    if (pendingException) {
      setSurpriseFlag(MemExceededFlag);
    } else {
      pendingException = generate_memory_exceeded_exception(wh);
    }
  }
  if (flags & PendingGCFlag) {
    if (StickyFlags & PendingGCFlag) {
      clearSurpriseFlag(PendingGCFlag);
    }
    if (RuntimeOption::EvalEnableGC) {
      MM().collect("surprise");
    } else {
      MM().checkHeap("surprise");
    }
  }
  if (flags & SignaledFlag) {
    HHVM_FN(pcntl_signal_dispatch)();
  }

  if (flags & PendingPerfEventFlag) {
    if (StickyFlags & PendingPerfEventFlag) {
      clearSurpriseFlag(PendingPerfEventFlag);
    }
    perf_event_consume(record_perf_mem_event);
  }

  if (pendingException) {
    pendingException->throwException();
  }
  return flags;
}