Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
///////////////////////////////////////////////////////////////////////////////
//
// FILE
//
// EAPSessionTable.cpp
//
// SYNOPSIS
//
// This file defines the class EAPSessionTable.
//
// MODIFICATION HISTORY
//
// 04/28/1998 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <eapsessiontable.h>
//////////
// Get the system time as a 64-bit integer.
//////////
inline DWORDLONG getCurrentTime() throw () { ULARGE_INTEGER ft; GetSystemTimeAsFileTime((LPFILETIME)&ft); return ft.QuadPart; }
// Session timeout defaults to 2 minutes.
// Max. sessions defaults to 4096.
EAPSessionTable::EAPSessionTable() : byID(0x400), sessionTimeout(1200000000ui64), maxSessions(0x1000) { }
EAPSessionTable::~EAPSessionTable() { clear(); }
//////////
// Externally the session timeout is expressed in milliseconds, but internally
// we store it in 100 nsec intervals to facilitate working with FILETIME.
//////////
DWORD EAPSessionTable::getSessionTimeout() const throw () { return (DWORD)(sessionTimeout / 10000); }
void EAPSessionTable::setSessionTimeout(DWORD newVal) throw () { sessionTimeout = 10000 * (DWORDLONG)newVal; }
void EAPSessionTable::clear() throw () { _serialize
// Delete all the sessions.
for (SessionTable::iterator i = byID.begin(); i.more(); ++i) { delete i->first; }
// Clear the collections.
byID.clear(); byExpiry.clear(); }
void EAPSessionTable::insert(EAPSession* session) { _serialize
// Make room for the new session.
while (byExpiry.size() >= maxSessions) { evictOldest(); }
// Evict all expired sessions. We do this before the insert to avoid
// unnecessary resizing of the session table.
DWORDLONG now = getCurrentTime(); evict(now);
// Compute the expiry of this session.
now += sessionTimeout;
// It must be the most recent, so insert it at the front of the list.
byExpiry.push_front(SessionList::value_type(now, session));
try { // We can use multi_insert since the session ID is guaranteed to be unique.
byID.multi_insert(SessionTable::value_type(session, byExpiry.begin())); } catch (const std::bad_alloc&) { byExpiry.pop_front(); throw; } }
EAPSession* EAPSessionTable::remove(DWORD key) throw () { _serialize
// First evict all expired sessions since the requested session may have
// expired.
evict(getCurrentTime());
const SessionEntry* entry = byID.find(key);
if (entry) { // Save the session pointer we're going to return.
EAPSession* session = entry->first;
// Erase from the expiry list ...
byExpiry.erase(entry->second);
// ... and the session table.
byID.erase(key);
return session; }
// Not found, so return NULL.
return NULL; }
void EAPSessionTable::evict(DWORDLONG now) throw () { // Loop until the list is empty or the oldest session hasn't expired.
while (!byExpiry.empty() && byExpiry.back().first <= now) { evictOldest(); } }
void EAPSessionTable::evictOldest() throw () { // We have an expired session, so erase it from the table.
byID.erase(byExpiry.back().second->getID());
// Clean up the session object.
delete byExpiry.back().second;
// Remove from the list.
byExpiry.pop_back(); }
|