Example #1
0
void queue::check_timeouts()
{
	struct timeval tv;
	gettimeofday(&tv, NULL);

	// check no more then once in 1 second
	//TODO: make timeout check interval configurable
	if ((tv.tv_sec - m_last_timeout_check_time) < 1) {
		return;
	}
	m_last_timeout_check_time = tv.tv_sec;

	LOG_INFO("checking timeouts: %ld waiting chunks", m_wait_ack.size());

	auto i = m_wait_ack.begin();
	while (i != m_wait_ack.end()) {
		int chunk_id = i->first;
		auto chunk = i->second;

		if (chunk->get_time() > tv.tv_sec) {
			++i;
			continue;
		}

		// Time passed but chunk still is not complete
		// so we must replay unacked items from it.
		LOG_ERROR("chunk %d timed out, returning back to the popping line, current time: %ld, chunk expiration time: %f",
				chunk_id, tv.tv_sec, chunk->get_time());

		// There are two cases when chunk can still be in m_chunks
		// while experiencing a timeout:
		// 1) if it's a single chunk in the queue (and serves both
		//    as a push and a pop/ack target)
		// 2) if iteration of this chunk was preempted by other timed out chunk
		//    and then later this chunk timed out in its turn
		// Timeout requires switch chunk's iteration into the replay mode.

		auto inserted = m_chunks.insert({chunk_id, chunk});
		if (!inserted.second) {
			LOG_INFO("chunk %d is already in popping line", chunk_id);
		} else {
			LOG_INFO("chunk %d inserted back to the popping line anew", chunk_id);
		}
		chunk->reset_iteration();

		auto hold = i;
		++i;
		m_wait_ack.erase(hold);

		// number of popped but still unacked entries
		m_statistics.timeout_count += (chunk->meta().low_mark() - chunk->meta().acked());
	}
}
  void run(InstanceKlass* root) {
    ALGO* algo = static_cast<ALGO*>(this);

    reset_iteration();

    void* algo_data = algo->new_node_data(root);
    push(root, algo_data);
    bool top_needs_visit = true;

    do {
      Node* top = current_top();
      if (top_needs_visit) {
        if (algo->visit() == false) {
          // algorithm does not want to continue along this path.  Arrange
          // it so that this state is immediately popped off the stack
          top->set_super_visited();
          top->set_all_interfaces_visited();
        }
        top_needs_visit = false;
      }

      if (top->has_visited_super() && top->has_visited_all_interfaces()) {
        algo->free_node_data(top->_algorithm_data);
        pop();
      } else {
        InstanceKlass* next = NULL;
        if (top->has_visited_super() == false) {
          next = top->next_super();
          top->set_super_visited();
        } else {
          next = top->next_interface();
          top->increment_visited_interface();
        }
        assert(next != NULL, "Otherwise we shouldn't be here");
        algo_data = algo->new_node_data(next);
        push(next, algo_data);
        top_needs_visit = true;
      }
    } while (!is_cancelled() && has_more_nodes());
  }
// ----------------------------------------------------------------------------
// -- Function    : StartIter()
// --
// -- Takes       : Nothing
// --
// -- Purpose     : Sets up the instance for iteration
void ValueHistoryTable::StartIter()
{
    reset_iteration();
}