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(); }