changed: added Cur structure

we have there two pointers: 
 Request * request;
 Session * session;
these are the current request and the current session


the session GC was moved to SessionManager (was in SessionContainer)



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@708 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2011-01-23 14:15:30 +00:00
parent 61ac29b2de
commit 915cabdf97
171 changed files with 2822 additions and 2650 deletions

View File

@@ -22,13 +22,19 @@
SessionManager::SessionManager()
{
temporary_session.id = 0;
session = &temporary_session;
session_tab.SetTmpSession(&temporary_session);
// thread work mode
work_mode = 1;
}
void SessionManager::SetRequest(Request * prequest)
void SessionManager::SetCur(Cur * pcur)
{
request = prequest;
session_tab.SetRequest(prequest);
cur = pcur;
session_tab.SetCur(pcur);
}
@@ -44,17 +50,13 @@ void SessionManager::SetSystem(System * psystem)
system = psystem;
}
void SessionManager::SetLastContainer(LastContainer * plast_container)
{
session_tab.SetLastContainer(plast_container);
last_container = plast_container;
}
void SessionManager::SetSynchro(Synchro * psynchro)
{
session_tab.SetSynchro(psynchro);
}
size_t SessionManager::Size()
{
@@ -103,52 +105,20 @@ return id;
void SessionManager::CreateTemporarySession()
{
SessionContainer::Iterator i = session_tab.FindById( 0 );
if( i == session_tab.End() )
{
Session s;
s.id = 0;
s.new_session = true;
session_tab.PushBack(s);
request->session = &session_tab.Back();
}
else
{
request->session = &(*i);
request->session->Clear(); // !! what about session.plugin_data?
request->session->id = 0;
request->session->new_session = false;
}
}
void SessionManager::CreateSession()
{
Session s;
int attempts = 100;
int attempts = 100;
bool added = false;
if( config->session_max == 0 || session_tab.Size() < config->session_max - 1 ) // -1 for the temporary session
new_session.Clear();
if( config->session_max == 0 || session_tab.Size() < config->session_max )
{
for( ; attempts > 0 ; --attempts )
for( ; !added && attempts > 0 ; --attempts )
{
s.id = CreateSessionId();
bool added = session_tab.PushBack(s);
if( added )
{
request->session = &session_tab.Back();
request->session->new_session = true;
log << log2 << "SM: created a new session: " << request->session->id << logend;
return;
}
new_session.id = CreateSessionId();
added = session_tab.PushBack(new_session);
}
}
else
@@ -156,10 +126,21 @@ int attempts = 100;
log << log2 << "SM: sessions limit exceeded (" << config->session_max << ")" << logend;
}
// there is a problem with generating a new session id
// we do not set a session cookie
CreateTemporarySession();
log << log1 << "SM: cannot create a session id (temporary used: with id 0)" << logend;
if( added )
{
session = &session_tab.Back();
session->new_session = true;
log << log2 << "SM: created a new session: " << session->id << logend;
}
else
{
// there is a problem with generating a new session id
// we do not set a session cookie
session = &temporary_session;
session->Clear();
session->new_session = false; // temporary session was initialized at the beginning
log << log1 << "SM: cannot create a session id (temporary used: with id 0)" << logend;
}
}
@@ -174,18 +155,18 @@ bool SessionManager::SetSessionFromCookie(const std::string & cookie)
return false;
// that session is in the table
request->session = &(*s);
request->session->new_session = false;
request->session->last_time = std::time(0);
request->session->tm_last_time = Time(request->session->last_time);
session = &(*s);
session->new_session = false;
session->last_time = std::time(0);
session->tm_last_time = Time(session->last_time);
if( request->method == Request::get )
request->session->last_time_get = request->session->last_time;
if( cur->request->method == Request::get )
session->last_time_get = session->last_time;
log << log2 << "SM: session: " << s->id;
log << log2 << "SM: session: " << session->id;
if( request->session->puser )
log << log2 << ", user: " << request->session->puser->name << ", id: " << request->session->puser->id;
if( session->puser )
log << log2 << ", user: " << session->puser->name << ", id: " << session->puser->id;
log << log2 << logend;
@@ -196,9 +177,9 @@ return true;
void SessionManager::SetSession()
{
CookieTab::iterator i = request->cookie_tab.find(config->http_session_id_name);
CookieTab::iterator i = cur->request->cookie_tab.find(config->http_session_id_name);
if( i == request->cookie_tab.end() )
if( i == cur->request->cookie_tab.end() )
{
CreateSession();
}
@@ -208,22 +189,12 @@ void SessionManager::SetSession()
{
// there is no such a session
// deleting the old cookie
request->cookie_tab.erase(i);
cur->request->cookie_tab.erase(i);
// and creating a new one
CreateSession();
}
}
// request->session is set now
if( request->session->new_session )
{
request->session->plugin_data.Resize(plugin.Size());
plugin.Call(WINIX_SESSION_CREATED);
}
plugin.Call(WINIX_SESSION_CHANGED);
}
@@ -252,6 +223,31 @@ void SessionManager::DeleteSessions()
void SessionManager::InitTmpSession()
{
Session * old_session = cur->session;
log << log4 << "SM: initializing temporary session" << logend;
cur->session = &temporary_session;
plugin.Call(WINIX_SESSION_CREATED);
cur->session = old_session;
}
void SessionManager::UninitTmpSession()
{
Session * old_session = cur->session;
log << log4 << "SM: uninitializing temporary session" << logend;
cur->session = &temporary_session;
cur->session->plugin_data.DeleteAll(); // this will call plugin.Call(WINIX_SESSION_REMOVE);
cur->session->plugin_data.Resize(0);
cur->session = old_session;
}
void SessionManager::LoadSessions()
@@ -259,20 +255,20 @@ void SessionManager::LoadSessions()
SessionParser sp;
SessionContainer::Iterator i;
// sessions will be overwritten (pointers are invalidated)
cur->session = &temporary_session;
sp.SetUsers(&system->users);
Session * old_session = request->session;
sp.Parse(config->session_file, session_tab);
i = session_tab.Begin();
for( ; i!=session_tab.End() ; ++i )
for(i=session_tab.Begin() ; i != session_tab.End() ; ++i)
{
i->plugin_data.Resize(plugin.Size());
request->session = &(*i);
cur->session = &(*i);
plugin.Call(WINIX_SESSION_CREATED);
}
request->session = old_session;
cur->session = &temporary_session;
}
@@ -316,24 +312,125 @@ void SessionManager::SaveSessions()
void SessionManager::StartGC()
Session * SessionManager::GetTmpSession()
{
session_tab.StartThread();
return &temporary_session;
}
// use it with Lock() and Unlock();
void SessionManager::PrepareToStopGC()
Session * SessionManager::GetCurSession()
{
session_tab.WakeUpThread();
}
void SessionManager::WaitForGC()
{
session_tab.WaitForThread();
return session;
}
/*
*
*
* sessions gc (second thread)
*
*
*/
void SessionManager::Work()
{
bool exit = false;
SessionContainer::IndexId::iterator i;
deleted = 0;
Lock();
i = session_tab.IdBegin();
Unlock();
while( !exit )
{
Lock();
CheckSession(i);
exit = synchro->was_stop_signal;
Unlock();
}
}
// it's called from the other thread (with Lock and Unlock)
void SessionManager::CheckSession(SessionContainer::IndexId::iterator & i)
{
const int deleted_max_at_once = 10;
if( i == session_tab.IdEnd() )
{
if( deleted > 0 )
{
deleted = 0;
log << logsave;
}
i = session_tab.IdBegin();
WaitForSignalSleep(10);
}
else
{
if( IsSessionOutdated(*i->second) )
{
DeleteSession(i++);
++deleted;
}
else
{
++i;
}
if( deleted >= deleted_max_at_once )
{
log << logsave;
WaitForSignalSleep(1);
deleted = 0;
}
}
}
// it's called from the other thread (with Lock and Unlock)
bool SessionManager::IsSessionOutdated(const Session & s) const
{
bool outdated;
if( s.remember_me )
outdated = s.last_time < std::time(0) - config->session_remember_max_idle;
else
outdated = s.last_time < std::time(0) - config->session_max_idle;
return outdated;
}
// it's called from the other thread (with Lock and Unlock)
void SessionManager::DeleteSession(SessionContainer::IdIterator i)
{
Session * del_session = &(*i->second);
if( del_session->puser )
last_container->UserLogout(del_session->puser->id, del_session->id);
session_tab.EraseById(i);
}
/*
*
*
* end of sessions gc
*
*
*/