--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_common/am/common/eap_timer_queue.cpp Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,1721 @@
+/*
+* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: EAP and WLAN authentication protocols.
+*
+*/
+
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+ #undef EAP_FILE_NUMBER_ENUM
+ #define EAP_FILE_NUMBER_ENUM 15
+ #undef EAP_FILE_NUMBER_DATE
+ #define EAP_FILE_NUMBER_DATE 1127594498
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#include "eap_am_memory.h"
+#include "eap_timer_queue.h"
+
+//--------------------------------------------------
+
+#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+ #define EAP_TRACE_TIMER EAP_TRACE_DEBUG
+#else
+ #define EAP_TRACE_TIMER(object, flags, parameters)
+#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c::~eap_timer_queue_event_c()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_initializer->timer_delete_data(m_id, m_data);
+ m_initializer = 0;
+ m_id = 0;
+ m_data = 0;
+ m_hash = 0;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c::eap_timer_queue_event_c(
+ abs_eap_am_tools_c * const tools,
+ abs_eap_base_timer_c * const initializer,
+ const u32_t id,
+ void * const data,
+ const u32_t p_time_ms)
+ : m_am_tools(tools)
+ , m_initializer(initializer)
+ , m_id(id)
+ , m_data(data)
+ , m_time_ms(p_time_ms)
+ , m_original_time_ms(p_time_ms)
+ , m_prev(0)
+ , m_next(0)
+ , m_hash(0)
+ , m_prev_same_time(0)
+ , m_next_same_time(0)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_event_c::get_time() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_time_ms;
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_event_c::get_original_time() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_original_time_ms;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c *eap_timer_queue_event_c::get_prev() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_prev;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c *eap_timer_queue_event_c::get_next() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_next;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c *eap_timer_queue_event_c::get_prev_same_time() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_prev_same_time;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_event_c *eap_timer_queue_event_c::get_next_same_time() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_next_same_time;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_hash_c * eap_timer_queue_event_c::get_hash() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_hash;
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_event_c::pulse_time(const u32_t resolution)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ if (m_time_ms >= resolution)
+ {
+ m_time_ms -= resolution;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return 0u;
+ }
+ else
+ {
+ u32_t remainder = resolution - m_time_ms;
+ m_time_ms = 0u;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return remainder;
+ }
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::decrease_time_left(const u32_t decrease_time)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ if (m_time_ms > decrease_time)
+ {
+ m_time_ms -= decrease_time;
+ }
+ else
+ {
+ m_time_ms = 0u;
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::increase_time_left(const u32_t increase_time)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_time_ms += increase_time;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::set_prev(eap_timer_queue_event_c * const prev)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_prev = prev;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::set_next(eap_timer_queue_event_c * const next)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_next = next;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::set_prev_same_time(eap_timer_queue_event_c * const prev_same_time)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_prev_same_time = prev_same_time;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::set_next_same_time(eap_timer_queue_event_c * const next_same_time)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_next_same_time = next_same_time;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_event_c::set_hash(eap_timer_queue_hash_c * const hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_hash = hash;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+abs_eap_base_timer_c * eap_timer_queue_event_c::get_initializer() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_initializer;
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_event_c::get_id() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_id;
+}
+
+//--------------------------------------------------
+
+//
+void * eap_timer_queue_event_c::get_data() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_data;
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_event_c::get_time_ms()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_time_ms;
+}
+
+//--------------------------------------------------
+//--------------------------------------------------
+//--------------------------------------------------
+
+//
+eap_timer_queue_hash_c::~eap_timer_queue_hash_c()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_atom = 0;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+ //--------------------------------------------------
+
+//
+eap_timer_queue_hash_c::eap_timer_queue_hash_c(
+ abs_eap_am_tools_c * const tools,
+ eap_timer_queue_event_c * const atom,
+ const u32_t index)
+ : m_am_tools(tools)
+ , m_index(index)
+ , m_atom(atom)
+ , m_prev(0)
+ , m_next(0)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_hash_c *eap_timer_queue_hash_c::get_next() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_next;
+}
+
+//--------------------------------------------------
+
+//
+eap_timer_queue_hash_c *eap_timer_queue_hash_c::get_prev() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_prev;
+}
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_hash_c::get_index() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_index;
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_hash_c::set_next(eap_timer_queue_hash_c * const next)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_next = next;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+void eap_timer_queue_hash_c::set_prev(eap_timer_queue_hash_c * const prev)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_prev = prev;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+eap_timer_queue_event_c * eap_timer_queue_hash_c::get_atom()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_atom;
+}
+
+//--------------------------------------------------
+
+i32_t eap_timer_queue_hash_c::compare(
+ const abs_eap_base_timer_c * const a_initializer,
+ const u32_t a_id,
+ const abs_eap_base_timer_c * const b_initializer,
+ const u32_t b_id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ if (a_id < b_id)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return -1;
+ }
+ else if (a_id > b_id)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return 1;
+ }
+ else if (a_initializer < b_initializer)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return -1;
+ }
+ else if (a_initializer > b_initializer)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return 1;
+ }
+ else
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return 0;
+ }
+}
+
+//--------------------------------------------------
+//--------------------------------------------------
+//--------------------------------------------------
+
+eap_timer_queue_c::~eap_timer_queue_c()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ deactivate_timer_queue();
+
+ // cancel_all_timers() must be called before destructor.
+ EAP_ASSERT_TOOLS(m_am_tools, m_timer_queue == 0);
+ EAP_ASSERT_TOOLS(m_am_tools, m_new_event_begin == 0);
+ EAP_ASSERT_TOOLS(m_am_tools, m_new_event_end == 0);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+eap_timer_queue_c::eap_timer_queue_c(
+ abs_eap_am_tools_c * const tools,
+ const u32_t timer_resolution_ms)
+ : m_am_tools(tools)
+ , m_timer_queue(0)
+ , m_new_event_begin(0)
+ , m_new_event_end(0)
+ , m_timer_resolution_ms(timer_resolution_ms)
+ , m_is_active(false)
+ , m_is_valid(false)
+ , m_use_eap_millisecond_timer(false)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ for(u32_t ind = 0; ind < EAP_TIMER_QUEUE_HASH_SIZE; ind++)
+ {
+ m_map[ind] = 0;
+ }
+
+ m_is_active = true;
+ m_is_valid = true;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+bool eap_timer_queue_c::get_use_eap_milli_second_timer()
+{
+ return m_use_eap_millisecond_timer;
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::set_use_eap_milli_second_timer(const bool use_eap_millisecond_timer)
+{
+ m_use_eap_millisecond_timer = use_eap_millisecond_timer;
+}
+
+//--------------------------------------------------
+
+u32_t eap_timer_queue_c::get_timer_resolution_ms()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_timer_resolution_ms;
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::set_timer_resolution_ms(const u32_t timer_resolution_ms)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ m_timer_resolution_ms = timer_resolution_ms;
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::deactivate_timer_queue()
+{
+ m_is_active = false;
+}
+
+//--------------------------------------------------
+
+// This is used in Symbian AM.
+eap_status_e eap_timer_queue_c::re_activate_timer_queue()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ m_is_active = true;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::trace_timer_event(
+ const eap_const_string prefix,
+ const eap_timer_queue_event_c * const event)
+{
+
+ EAP_UNREFERENCED_PARAMETER(prefix);
+ EAP_UNREFERENCED_PARAMETER(event);
+
+#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER_QUEUE,
+ (EAPL("TIMER: queue: %s, %s[0x%08x], original time %8d, ")
+ EAPL("time left %8d, initializer 0x%08x, ")
+ EAPL("id 0x%02x, data 0x%08x, prev 0x%08x, ")
+ EAPL("next 0x%08x, prev same time 0x%08x, next same time 0x%08x\n"),
+ prefix,
+ ((event == m_timer_queue || event->get_time() != 0) ? "-> ": " "),
+ event,
+ event->get_original_time(),
+ event->get_time(),
+ event->get_initializer(),
+ event->get_id(),
+ event->get_data(),
+ event->get_prev(),
+ event->get_next(),
+ event->get_prev_same_time(),
+ event->get_next_same_time()));
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::trace_timer()
+{
+#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ if ( ! (m_am_tools->get_trace_mask() & (TRACE_FLAGS_TIMER_QUEUE)))
+ {
+ return;
+ }
+
+ eap_timer_queue_event_c *cursor = m_timer_queue;
+ eap_timer_queue_event_c *prev = 0;
+ EAP_UNREFERENCED_PARAMETER(prev);
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER_QUEUE,
+ (EAPL("-------------------------------------------------------------------------\n")));
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER_QUEUE,
+ (EAPL("TIMER: current timer queue:\n")));
+
+ if (cursor == 0
+ && m_new_event_begin == 0)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER_QUEUE,
+ (EAPL("TIMER: queue: is empty\n")));
+ }
+
+
+ {
+ eap_timer_queue_event_c *pending = m_new_event_begin;
+
+ while(pending != 0)
+ {
+ trace_timer_event("new", pending);
+
+ pending = pending->get_next();
+ }
+ }
+
+
+ while(cursor != 0)
+ {
+ EAP_ASSERT(prev == cursor->get_prev());
+
+ {
+ eap_timer_queue_event_c *vertical = cursor;
+
+ while(vertical != 0)
+ {
+ trace_timer_event("old", vertical);
+
+ vertical = vertical->get_next_same_time();
+ }
+ }
+
+ prev = cursor;
+ cursor = cursor->get_next();
+
+ EAP_ASSERT(prev->get_next() == cursor);
+ }
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER_QUEUE,
+ (EAPL("-------------------------------------------------------------------------\n")));
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+#endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE)
+}
+
+//--------------------------------------------------
+
+u32_t eap_timer_queue_c::pulse_timer(
+ const u32_t elapsed_time_in_ms,
+ const bool can_call_timer_expired_when_true)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ u32_t next_sleep_time = get_timer_resolution_ms();
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: pulse_timer(%u), can_call_timer_expired_when_true %d\n"),
+ elapsed_time_in_ms,
+ can_call_timer_expired_when_true));
+
+ EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+ trace_timer();
+
+ if (m_timer_queue != 0)
+ {
+ u32_t remainder_time = m_timer_queue->pulse_time(elapsed_time_in_ms);
+
+ if (can_call_timer_expired_when_true == true)
+ {
+ while (m_timer_queue != 0
+ && m_timer_queue->get_time() == 0)
+ {
+ eap_timer_queue_event_c *current = m_timer_queue;
+
+ EAP_ASSERT(m_timer_queue->get_prev() == 0);
+ EAP_ASSERT(current->get_time() == 0);
+
+ if (current->get_next_same_time() != 0)
+ {
+ eap_timer_queue_event_c *next = current->get_next_same_time();
+
+ EAP_ASSERT(next->get_prev() == 0 && next->get_next() == 0);
+
+ next->set_prev_same_time(0);
+ next->set_next(m_timer_queue->get_next());
+
+ if (m_timer_queue->get_next() != 0)
+ {
+ m_timer_queue->get_next()->set_prev(next);
+ }
+
+ m_timer_queue = next;
+ }
+ else
+ {
+ m_timer_queue = m_timer_queue->get_next();
+ if (m_timer_queue != 0)
+ {
+ m_timer_queue->set_prev(0);
+ }
+ }
+
+ if (current != 0)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("TIMER: timer_expired(): [0x%08x]->initializer(0x%08x)->timer_expired(")
+ EAPL("id 0x%02x, data 0x%08x, original time %8d)\n"),
+ current,
+ current->get_initializer(),
+ current->get_id(),
+ current->get_data(),
+ current->get_original_time()));
+
+ remove_hash_of_timer_event(current);
+
+ current->set_prev_same_time(0);
+ current->set_next_same_time(0);
+ current->set_prev(0);
+ current->set_next(0);
+
+ current->get_initializer()->timer_expired(
+ current->get_id(),
+ current->get_data());
+
+ delete current;
+ }
+
+ if (remainder_time != 0u
+ && m_timer_queue != 0)
+ {
+ remainder_time = m_timer_queue->pulse_time(remainder_time);
+ }
+ } // while(m_timer_queue != 0
+ // && m_timer_queue->get_time() == 0)
+ } // if (can_call_timer_expired_when_true == true)
+ }
+
+
+ if (m_use_eap_millisecond_timer == true)
+ {
+ // New timer events are added here because the current
+ // pulse might be very long, and the long pulse will
+ // cause the new event expire immediately.
+ // By using this function the shortest timer events in the
+ // timer queue are handled and after that the new timer events
+ // are added to timer queue.
+ eap_status_e status = add_pending_timer();
+ if (status != eap_status_ok)
+ {
+ next_sleep_time = get_timer_resolution_ms();
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("ERROR: TIMER: add_pending_timer() status=%d, next_sleep_time=%d\n"),
+ status,
+ next_sleep_time));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ (void) EAP_STATUS_RETURN(m_am_tools, status);
+ return next_sleep_time;
+ }
+ }
+
+
+ if (m_timer_queue != 0)
+ {
+ next_sleep_time = m_timer_queue->get_time();
+ }
+ else
+ {
+ if (m_use_eap_millisecond_timer == true)
+ {
+ next_sleep_time = EAP_TIMER_QUEUE_LONG_SLEEP_TIME;
+ }
+ }
+
+ trace_timer();
+
+ if (m_use_eap_millisecond_timer == false)
+ {
+ next_sleep_time = get_timer_resolution_ms();
+ }
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: next_sleep_time=%d\n"),
+ next_sleep_time));
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return next_sleep_time;
+}
+
+
+//--------------------------------------------------
+
+bool eap_timer_queue_c::get_timer_queue_is_empty()
+{
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: get_timer_queue_is_empty(): m_timer_queue=0x%08x, m_new_event_begin=0x%08x\n"),
+ m_timer_queue,
+ m_new_event_begin));
+
+ return (m_timer_queue == 0 && m_new_event_begin == 0);
+
+#else
+
+ return true;
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+}
+
+//--------------------------------------------------
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+eap_status_e eap_timer_queue_c::add_hash_of_timer_event(
+ eap_timer_queue_event_c * const event,
+ const abs_eap_base_timer_c * const initializer,
+ const u32_t id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ const u32_t index = hash(EAP_TIMER_QUEUE_HASH_SIZE, initializer, id);
+
+ if (index >= EAP_TIMER_QUEUE_HASH_SIZE)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("ERROR: TIMER HASH: add_handler(): initializer 0x%08x, ")
+ EAPL("id 0x%02x, index %d >= EAP_TIMER_QUEUE_HASH_SIZE %d\n"),
+ initializer,
+ id,
+ index,
+ EAP_TIMER_QUEUE_HASH_SIZE));
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_hashed_index);
+ }
+
+ eap_timer_queue_hash_c *hash = new eap_timer_queue_hash_c(m_am_tools, event, index);
+
+ if (hash == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ event->set_hash(hash);
+
+ eap_timer_queue_hash_c *cursor = m_map[index];
+ eap_timer_queue_hash_c *last_cursor = 0;
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER HASH: add_handler(): initializer 0x%08x, id 0x%02x, index %d\n"),
+ initializer,
+ id,
+ index));
+
+ while (cursor != 0)
+ {
+ if (hash->compare(hash->get_atom()->get_initializer(),
+ hash->get_atom()->get_id(),
+ cursor->get_atom()->get_initializer(),
+ cursor->get_atom()->get_id()) == 0)
+ {
+ // match
+ break;
+ }
+ last_cursor = cursor;
+ cursor = cursor->get_next();
+ }
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER HASH: add_hash_of_timer_event(): hash 0x%08x\n"),
+ hash));
+
+ EAP_ASSERT(hash->get_index() == index);
+
+ if (last_cursor != 0)
+ {
+ if (last_cursor->get_next() != 0)
+ {
+ last_cursor->get_next()->set_prev(hash);
+ }
+ hash->set_next(last_cursor->get_next());
+ last_cursor->set_next(hash);
+ hash->set_prev(last_cursor);
+ }
+ else
+ {
+ if (m_map[index] != 0)
+ {
+ m_map[index]->set_prev(hash);
+ }
+ hash->set_next(m_map[index]);
+ m_map[index] = hash;
+ hash->set_prev(0);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+//--------------------------------------------------
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+eap_timer_queue_event_c * eap_timer_queue_c::get_hashed_timer_event(
+ const abs_eap_base_timer_c * const initializer,
+ const u32_t id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ const u32_t index = hash(EAP_TIMER_QUEUE_HASH_SIZE, initializer, id);
+
+ if (index >= EAP_TIMER_QUEUE_HASH_SIZE)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("ERROR: TIMER HASH: get_handler(): initializer 0x%08x, ")
+ EAPL("id 0x%02x, index %d >= EAP_TIMER_QUEUE_HASH_SIZE %d\n"),
+ initializer,
+ id,
+ index,
+ EAP_TIMER_QUEUE_HASH_SIZE));
+ return 0;
+ }
+
+ eap_timer_queue_hash_c *cursor = m_map[index];
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER HASH: get_handler(): initializer 0x%08x, id 0x%02x, index %d\n"),
+ initializer,
+ id,
+ index));
+
+ while (cursor != 0)
+ {
+ eap_timer_queue_event_c * const event = cursor->get_atom();
+
+ if (cursor->compare(initializer,
+ id,
+ event->get_initializer(),
+ event->get_id()) == 0)
+ {
+ // match
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER HASH: match: get_handler(): initializer 0x%08x, ")
+ EAPL("id 0x%02x, index %d, atom 0x%08x\n"),
+ initializer,
+ id,
+ index,
+ cursor->get_atom()));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return cursor->get_atom();
+ }
+
+ cursor = cursor->get_next();
+ }
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("WARNING: TIMER HASH: not found: get_handler(): ")
+ EAPL("initializer 0x%08x, id 0x%02x, index %d\n"),
+ initializer,
+ id,
+ index));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return 0;
+}
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+//--------------------------------------------------
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+eap_status_e eap_timer_queue_c::remove_hash_of_timer_event(
+ eap_timer_queue_event_c * const event)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ if (event == 0
+ || event->get_hash() == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+ }
+
+ eap_timer_queue_hash_c *hash = event->get_hash();
+ event->set_hash(0);
+
+ if (hash->get_prev() != 0)
+ {
+ // Remove from middle.
+ EAP_ASSERT(m_map[hash->get_index()] != hash);
+
+ if (hash->get_next() != 0)
+ {
+ hash->get_next()->set_prev(hash->get_prev());
+ }
+ hash->get_prev()->set_next(hash->get_next());
+ }
+ else
+ {
+ // Remove the first item.
+ EAP_ASSERT(m_map[hash->get_index()] == hash);
+ EAP_ASSERT(hash->get_prev() == 0);
+
+ if (hash->get_next() != 0)
+ {
+ hash->get_next()->set_prev(hash->get_prev());
+ }
+ m_map[hash->get_index()] = hash->get_next();
+ EAP_ASSERT(m_map[hash->get_index()] == 0
+ || m_map[hash->get_index()]->get_prev() == 0);
+ }
+
+ delete hash;
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+//--------------------------------------------------
+
+//
+u32_t eap_timer_queue_c::hash(
+ const u32_t size,
+ const abs_eap_base_timer_c * const initializer,
+ const u32_t id) const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ u32_t ihash = 0x55555555;
+
+ ihash += static_cast<u32_t>(id);
+ ihash += reinterpret_cast<u32_t>(initializer);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return ihash % size;
+}
+
+//--------------------------------------------------
+
+void eap_timer_queue_c::add_end_of_vertical_list(
+ eap_timer_queue_event_c * const begin,
+ eap_timer_queue_event_c * const event)
+{
+ EAP_ASSERT(begin != 0 && event != 0);
+
+ eap_timer_queue_event_c * previous = 0;
+ eap_timer_queue_event_c * current = begin;
+
+ while (current != 0)
+ {
+ previous = current;
+ current = current->get_next_same_time();
+ }
+
+ // Add to the vertical list of previous time.
+ event->set_next_same_time(previous->get_next_same_time());
+ if (previous->get_next_same_time() != 0)
+ {
+ previous->get_next_same_time()->set_prev_same_time(event);
+ }
+ previous->set_next_same_time(event);
+ event->set_prev_same_time(previous);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::add_timer(
+ eap_timer_queue_event_c *event)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ eap_status_e status = add_hash_of_timer_event(
+ event,
+ event->get_initializer(),
+ event->get_id());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+
+ if (m_timer_queue == 0)
+ {
+ m_timer_queue = event;
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] add_timer(initializer 0x%08x, ")
+ EAPL("id 0x%02x, data 0x%08x, time %d)\n"),
+ m_timer_queue,
+ event->get_initializer(),
+ event->get_id(),
+ event->get_data(),
+ event->get_time_ms()));
+ }
+ else
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x]\n"),
+ event));
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: initializer 0x%08x\n"),
+ event->get_initializer()));
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: id 0x%02x\n"),
+ event->get_id()));
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: data 0x%08x\n"),
+ event->get_data()));
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: time %d\n"),
+ event->get_time_ms()));
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] add_timer(initializer 0x%08x, ")
+ EAPL("id 0x%02x, data 0x%08x, time %d)\n"),
+ event,
+ event->get_initializer(),
+ event->get_id(),
+ event->get_data(),
+ event->get_time_ms()));
+
+ eap_timer_queue_event_c *current = m_timer_queue;
+ eap_timer_queue_event_c *prev = 0;
+ u32_t time_ms_sum = 0u;
+ u32_t tmp_time_ms = 0u;
+
+
+ while(current != 0)
+ {
+ tmp_time_ms = current->get_time();
+
+ time_ms_sum += tmp_time_ms;
+
+ if (time_ms_sum >= event->get_time())
+ {
+ // Time segment found.
+ // tmp_time_ms is decremented from time_ms_sum
+ // because of we need time sum before current.
+ // New event is added before current.
+ if (time_ms_sum > event->get_time())
+ {
+ time_ms_sum -= tmp_time_ms;
+ }
+ else
+ {
+ // current points to the same time sum.
+ }
+ break;
+ }
+
+ prev = current;
+ current = current->get_next();
+ } // while(current != 0)
+
+
+ if (prev == 0
+ && time_ms_sum == 0)
+ {
+ // Add to first.
+
+ if (m_timer_queue != 0
+ && m_timer_queue->get_time() == event->get_time())
+ {
+ // Add to the first vertical list, in the end of the vertical list.
+ m_timer_queue->decrease_time_left(event->get_time()); // event->get_time() == 0.
+ add_end_of_vertical_list(m_timer_queue, event);
+ }
+ else
+ {
+ if (m_timer_queue != 0)
+ {
+ m_timer_queue->decrease_time_left(event->get_time());
+ }
+ event->set_next(m_timer_queue);
+ m_timer_queue->set_prev(event);
+ m_timer_queue = event;
+ }
+ }
+ else if (current != 0
+ && time_ms_sum == event->get_time())
+ {
+ add_end_of_vertical_list(current, event);
+ event->decrease_time_left(event->get_time()); // event->get_time() == 0.
+ }
+ else
+ {
+ // Add new vertical list to middle.
+ EAP_ASSERT(prev != 0);
+
+ event->decrease_time_left(time_ms_sum);
+
+ if (prev != 0)
+ {
+ event->set_next(prev->get_next());
+ if (prev->get_next() != 0)
+ {
+ prev->get_next()->set_prev(event);
+ prev->get_next()->decrease_time_left(event->get_time());
+ }
+ prev->set_next(event);
+ event->set_prev(prev);
+ }
+ }
+ }
+
+ trace_timer();
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::add_new_pending_timer(
+ eap_timer_queue_event_c *event)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] add_new_pending_timer(initializer 0x%08x, ")
+ EAPL("id 0x%02x, data 0x%08x, time %d)\n"),
+ m_timer_queue,
+ event->get_initializer(),
+ event->get_id(),
+ event->get_data(),
+ event->get_time_ms()));
+
+ // Adds the new event to the end of the list to keep the order of events correct.
+ EAP_ASSERT(m_new_event_begin == 0
+ && m_new_event_end == 0
+ || m_new_event_begin != 0
+ && m_new_event_end != 0);
+
+ if (m_new_event_begin == 0
+ && m_new_event_end == 0)
+ {
+ // Adds to the begin.
+ m_new_event_begin = event;
+ m_new_event_end = event;
+ }
+ else
+ {
+ // Adds to the end.
+ m_new_event_end->set_next(event);
+ m_new_event_end = event;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::set_timer(
+ abs_eap_base_timer_c * const initializer,
+ const u32_t id,
+ void * const data,
+ const u32_t time_ms)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_STACK_TRACE(initializer);
+
+ if (m_is_active == false)
+ {
+ initializer->timer_delete_data(id, data);
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("WARNING: TIMER: not accepted, timer queue is inactive: ")
+ EAPL("[0x%08x] set_timer(initializer 0x%08x, id 0x%02x, data 0x%08x, time %d)\n"),
+ m_timer_queue,
+ initializer,
+ id,
+ data,
+ time_ms));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+ }
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+ trace_timer();
+
+ eap_timer_queue_event_c *event = new eap_timer_queue_event_c(
+ m_am_tools,
+ initializer,
+ id,
+ data,
+ time_ms);
+
+ if (event == 0)
+ {
+ initializer->timer_delete_data(id, data);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+
+ if (m_use_eap_millisecond_timer == true)
+ {
+ // The next pulse_timer() function call will add the event to timer queue.
+ eap_status_e status = add_new_pending_timer(event);
+ if (status != eap_status_ok)
+ {
+ delete event;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+ else
+ {
+ eap_status_e status = add_timer(event);
+ if (status != eap_status_ok)
+ {
+ delete event;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::add_pending_timer()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ eap_status_e status(eap_status_ok);
+
+ while (m_new_event_begin != 0)
+ {
+ eap_timer_queue_event_c *event = m_new_event_begin;
+
+ m_new_event_begin = m_new_event_begin->get_next();
+
+ if (m_new_event_begin == 0)
+ {
+ m_new_event_end = 0;
+ }
+
+ event->set_next(0);
+
+ eap_status_e status = add_timer(event);
+ if (status != eap_status_ok)
+ {
+ event->get_initializer()->timer_expired(
+ event->get_id(),
+ event->get_data());
+
+ delete event;
+
+ // Read all pending events. Even the addition failed.
+ // We might have too less mamory.
+ }
+ } // while()
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::cancel_pending_timer(
+ abs_eap_base_timer_c * const initializer,
+ const u32_t id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_STACK_TRACE(initializer);
+
+ eap_timer_queue_event_c *previous = 0;
+ eap_timer_queue_event_c *event = m_new_event_begin;
+
+ while (event != 0)
+ {
+ if (initializer == event->get_initializer()
+ && id == event->get_id())
+ {
+ // Remove this pending event.
+ eap_timer_queue_event_c *remove = event;
+ event = event->get_next();
+
+ if (remove == m_new_event_end)
+ {
+ m_new_event_end = previous;
+ }
+
+ remove->set_next(0);
+ delete remove;
+
+ if (previous != 0)
+ {
+ previous->set_next(event);
+ }
+ else
+ {
+ m_new_event_begin = event;
+ }
+ }
+ else
+ {
+ previous = event;
+ event = event->get_next();
+ }
+ } // while()
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::cancel_timer(
+ abs_eap_base_timer_c * const initializer,
+ const u32_t id)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_STACK_TRACE(initializer);
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+
+ trace_timer();
+
+
+ eap_status_e status = cancel_pending_timer(
+ initializer,
+ id);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+
+ if (m_timer_queue == 0)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: empty queue, [0x%08x] cancel_timer(initializer 0x%08x, id 0x%02x)\n"),
+ m_timer_queue,
+ initializer,
+ id));
+ }
+ else
+ {
+ eap_timer_queue_event_c * cursor = get_hashed_timer_event(initializer, id);
+
+ while(cursor != 0)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] cancel_timer(initializer 0x%08x, ")
+ EAPL("id 0x%02x, original time %8d)\n"),
+ cursor,
+ initializer,
+ id,
+ cursor->get_original_time()));
+
+ if (cursor == m_timer_queue)
+ {
+ // The first event will be removed.
+ EAP_ASSERT(cursor->get_prev() == 0);
+
+ if (m_timer_queue->get_next_same_time() != 0)
+ {
+ eap_timer_queue_event_c * new_first = m_timer_queue->get_next_same_time();
+ EAP_ASSERT(new_first->get_next() == 0 && new_first->get_prev() == 0);
+ new_first->set_prev_same_time(0);
+ new_first->set_next(m_timer_queue->get_next());
+ if (m_timer_queue->get_next() != 0)
+ {
+ m_timer_queue->get_next()->set_prev(new_first);
+ }
+ m_timer_queue = new_first;
+ m_timer_queue->increase_time_left(cursor->get_time());
+ }
+ else
+ {
+ if (cursor->get_next() != 0)
+ {
+ cursor->get_next()->increase_time_left(cursor->get_time());
+ cursor->get_next()->set_prev(0);
+ }
+ m_timer_queue = cursor->get_next();
+ }
+
+ cursor->set_prev(0);
+ cursor->set_next(0);
+ cursor->set_prev_same_time(0);
+ cursor->set_next_same_time(0);
+ remove_hash_of_timer_event(cursor);
+ delete cursor;
+ }
+ else if (cursor->get_prev_same_time() != 0)
+ {
+ // Event from the vertical time list will be removed.
+ EAP_ASSERT(cursor->get_next() == 0 && cursor->get_prev() == 0);
+ cursor->get_prev_same_time()->set_next_same_time(cursor->get_next_same_time());
+ if (cursor->get_next_same_time() != 0)
+ {
+ cursor->get_next_same_time()->set_prev_same_time(cursor->get_prev_same_time());
+ }
+ cursor->set_prev(0);
+ cursor->set_next(0);
+ cursor->set_prev_same_time(0);
+ cursor->set_next_same_time(0);
+ remove_hash_of_timer_event(cursor);
+ delete cursor;
+ }
+ else // if (cursor->get_prev_same_time() == 0)
+ {
+ EAP_ASSERT(cursor->get_prev() != 0);
+
+ // Event from middle or end of the horizontal queue will be removed.
+ if (cursor->get_next_same_time() != 0)
+ {
+ // Next on the vertical list will replace the removed timer event.
+ eap_timer_queue_event_c * new_first = cursor->get_next_same_time();
+
+ new_first->increase_time_left(cursor->get_time());
+
+ new_first->set_next(cursor->get_next());
+ if (cursor->get_next() != 0)
+ {
+ cursor->get_next()->set_prev(new_first);
+ }
+ new_first->set_prev(cursor->get_prev());
+ if (cursor->get_prev() != 0)
+ {
+ cursor->get_prev()->set_next(new_first);
+ }
+ new_first->set_prev_same_time(0);
+ }
+ else
+ {
+ // No other timer events are in the vertical list.
+ cursor->get_prev()->set_next(cursor->get_next());
+ if (cursor->get_next() != 0)
+ {
+ cursor->get_next()->set_prev(cursor->get_prev());
+ cursor->get_next()->increase_time_left(cursor->get_time());
+ }
+ }
+ cursor->set_prev(0);
+ cursor->set_next(0);
+ cursor->set_prev_same_time(0);
+ cursor->set_next_same_time(0);
+ remove_hash_of_timer_event(cursor);
+ delete cursor;
+ }
+ cursor = get_hashed_timer_event(initializer, id);
+ } // while()
+ }
+
+ trace_timer();
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e eap_timer_queue_c::cancel_all_timers()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+ EAP_STACK_TRACE(0);
+
+ deactivate_timer_queue();
+
+ while (m_new_event_begin != 0)
+ {
+ eap_timer_queue_event_c *event = m_new_event_begin;
+
+ m_new_event_begin = m_new_event_begin->get_next();
+
+ event->set_next(0);
+
+ delete event;
+ event = 0;
+ } // while()
+
+ m_new_event_end = 0;
+
+#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] cancel_all_timers()\n"),
+ m_timer_queue));
+
+ EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+ eap_status_e status = add_pending_timer();
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ trace_timer();
+
+ if (m_timer_queue == 0)
+ {
+ // Nothing to do.
+ }
+ else
+ {
+ eap_timer_queue_event_c *cursor = m_timer_queue;
+
+ while (cursor != 0)
+ {
+ // The first event will be removed.
+ m_timer_queue = m_timer_queue->get_next();
+
+ while (cursor != 0)
+ {
+ EAP_TRACE_TIMER(
+ m_am_tools,
+ TRACE_FLAGS_TIMER,
+ (EAPL("TIMER: [0x%08x] cancel_all_timers()\n"),
+ cursor));
+
+ eap_timer_queue_event_c *next = cursor->get_next_same_time();
+
+ cursor->set_prev(0);
+ cursor->set_next(0);
+
+ remove_hash_of_timer_event(cursor);
+
+ delete cursor;
+
+ cursor = next;
+ } // while()
+
+ cursor = m_timer_queue;
+ } // while()
+ }
+
+ trace_timer();
+
+#endif //#if !defined(NO_EAP_TIMER_QUEUE)
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+bool eap_timer_queue_c::get_is_valid() const
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return m_is_valid;
+}
+
+//--------------------------------------------------
+
+
+
+
+// End.