diff --git a/core/plugindata.cpp b/core/plugindata.cpp index ef2c875..cf32b31 100755 --- a/core/plugindata.cpp +++ b/core/plugindata.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2010, Tomasz Sowa + * Copyright (c) 2008-2012, Tomasz Sowa * All rights reserved. * */ @@ -66,9 +66,7 @@ void PluginData::DeleteAll() return; plugin.Call(WINIX_SESSION_REMOVE); - - for(size_t i=0 ; isession = &(*i); + cur->session->plugin_data.DeleteAll(); // it's better to call it here instead of the destructor table.erase(i++); } @@ -71,6 +72,10 @@ void SessionContainer::EraseById(IdIterator i) cur->session = &(*i->second); log << log4 << "SC: deleting session, id: " << i->second->id << logend; + + // call first DeleteAll() because if not then it would be called from the desctructor + // and there'll be a problem if it throws an exception there + i->second->plugin_data.DeleteAll(); table.erase(i->second); index_id.erase(i); table_size -= 1; diff --git a/core/sessioncontainer.h b/core/sessioncontainer.h index 1250a67..1c088f0 100755 --- a/core/sessioncontainer.h +++ b/core/sessioncontainer.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2010, Tomasz Sowa + * Copyright (c) 2008-2012, Tomasz Sowa * All rights reserved. * */ @@ -24,7 +24,7 @@ class SessionContainer { public: - // when deleting Sessions you should set request.session into the session object + // when deleting Sessions you should set cur->session into the session object // this allows to delete plugins session data // because a session object has plugin_data object // and in its destructor the plugin.Call(WINIX_SESSION_REMOVE) is called diff --git a/main/main.cpp b/main/main.cpp index 9c2f54a..58509f0 100755 --- a/main/main.cpp +++ b/main/main.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2011, Tomasz Sowa + * Copyright (c) 2008-2012, Tomasz Sowa * All rights reserved. * */ @@ -141,6 +141,7 @@ int main(int argv, char ** argc) app.Lock(); plugin.Call(WINIX_CLOSE); app.Close(); + // now all sessions are cleared app.Unlock(); app.WaitForThreads(); diff --git a/plugins/ticket/createticket.cpp b/plugins/ticket/createticket.cpp index d5e4907..f81be77 100755 --- a/plugins/ticket/createticket.cpp +++ b/plugins/ticket/createticket.cpp @@ -136,9 +136,9 @@ PT::Space & CreateTicket::PrepareSpace() cur->session->plugin_data.Get(ticket_info->plugin_id) ); long dir_id = cur->request->dir_tab.back()->id; - PT::Space & space = session_data->GetSpace(dir_id, session_data->create_space_map); + PT::Space & new_space = session_data->GetNewSpace(dir_id, session_data->create_space_map); -return space; +return new_space; } @@ -174,7 +174,8 @@ void CreateTicket::MakeGet() ticket_info->ticket = &ticket; ticket_info->item = &cur->request->item; - ticket_info->CopyTicketSpace(meta, *ticket_info->item); + // copy meta info to display correctly new files + ticket_info->CopyTicketSpace(meta, cur->request->item); } diff --git a/plugins/ticket/editticket.cpp b/plugins/ticket/editticket.cpp index ac53d95..2d7ce42 100755 --- a/plugins/ticket/editticket.cpp +++ b/plugins/ticket/editticket.cpp @@ -144,17 +144,21 @@ PT::Space & EditTicket::PrepareSpace() bool is_new; long file_id = cur->request->item.id; - PT::Space & space = session_data->GetSpace(file_id, session_data->edit_space_map, &is_new); + PT::Space & new_space = session_data->GetNewSpace(file_id, session_data->edit_space_map, &is_new); if( is_new ) { PT::Space * ticket_space = cur->request->item.meta.FindSpace(L"ticket"); if( ticket_space ) - space = *ticket_space; + { + new_space = *ticket_space; + PT::Space & old_space = session_data->GetOldSpace(file_id, session_data->edit_space_map); + old_space = new_space; + } } -return space; +return new_space; } @@ -191,7 +195,8 @@ void EditTicket::MakeGet() ticket_info->ticket = &ticket; ticket_info->item = &cur->request->item; - ticket_info->CopyTicketSpace(meta, *ticket_info->item); + // copy meta info to display correctly new files + ticket_info->CopyTicketSpace(meta, cur->request->item); } diff --git a/plugins/ticket/init.cpp b/plugins/ticket/init.cpp index 59adf2d..41c5d28 100755 --- a/plugins/ticket/init.cpp +++ b/plugins/ticket/init.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2010, Tomasz Sowa + * Copyright (c) 2010-2012, Tomasz Sowa * All rights reserved. * */ @@ -124,8 +124,12 @@ void CreateSession(PluginInfo & info) void RemoveSession(PluginInfo & info) { - delete info.plugin_data_base; - log << log4 << "Ticket: removed ticket plugin data: " << (void*)info.plugin_data_base << logend; + if( info.plugin_data_base ) + { + info.plugin_data_base->Clear(); + delete info.plugin_data_base; + log << log4 << "Ticket: removed ticket plugin data: " << (void*)info.plugin_data_base << logend; + } } diff --git a/plugins/ticket/sessiondata.cpp b/plugins/ticket/sessiondata.cpp index 427c16f..3598691 100755 --- a/plugins/ticket/sessiondata.cpp +++ b/plugins/ticket/sessiondata.cpp @@ -7,6 +7,7 @@ * */ +#include #include "sessiondata.h" @@ -19,59 +20,134 @@ SessionData::SessionData() } + SessionData::~SessionData() { - RemoveFiles(create_space_map); - RemoveFiles(edit_space_map); + Clear(); +} + + +void SessionData::Clear() +{ + RemoveFiles(create_space_map, false); + RemoveFiles(edit_space_map, true); } - - -void SessionData::RemoveFiles(SessionData::SpaceMap & space_map) +void SessionData::RemoveFiles(SessionData::SpaceMap & space_map, bool only_stale_files) { SpaceMap::iterator i; if( fun_rm ) { for(i=space_map.begin() ; i!=space_map.end() ; ++i) - RemoveFiles(i->second); + { + if( only_stale_files ) + RemoveAllStaleFiles(i->second.new_space, i->second.old_space); + else + RemoveAllFiles(i->second.new_space); + } space_map.clear(); } } -void SessionData::RemoveFiles(PT::Space & space) + +void SessionData::RemoveAllFiles(PT::Space & new_space) { + std::vector new_file_tab; + BuildFileList(new_file_tab, new_space); + + for(size_t i=0 ; iRemoveItemById(new_file_tab[i]); +} + + + +void SessionData::RemoveAllStaleFiles(PT::Space & new_space, PT::Space & old_space) +{ + std::vector new_file_tab; + std::vector old_file_tab; + size_t n = 0; + size_t o = 0; + + BuildFileList(new_file_tab, new_space); + BuildFileList(old_file_tab, old_space); + + std::sort(new_file_tab.begin(), new_file_tab.end()); + std::sort(old_file_tab.begin(), old_file_tab.end()); + + // removes only those items present on new_file_tab + // but not existing on old_space_tab + + while( n < new_file_tab.size() && o < old_file_tab.size() ) + { + if( new_file_tab[n] < old_file_tab[o] ) + { + fun_rm->RemoveItemById(new_file_tab[n]); + n += 1; + } + else + if( new_file_tab[n] == old_file_tab[o] ) + { + n += 1; + o += 1; + } + else + { + o += 1; + } + } + + while( n < new_file_tab.size() ) + { + fun_rm->RemoveItemById(new_file_tab[n]); + n += 1; + } +} + + + + + +void SessionData::BuildFileList(std::vector & file_tab, PT::Space & space) +{ + file_tab.clear(); + for(size_t i=0 ; i & file_tab, PT::Space & space) +{ + for(size_t i=0 ; iRemoveItemById(file_id); - } - } + long file_id = Tol(*file_id_str); + file_tab.push_back(file_id); } } } } + + Ticket & SessionData::GetTicket(long id, SessionData::TicketMap & ticket_map, bool * is_new) { std::pair res = ticket_map.insert( std::make_pair(id, Ticket()) ); @@ -84,17 +160,27 @@ return res.first->second; -PT::Space & SessionData::GetSpace(long id, SpaceMap & space_map, bool * is_new) +PT::Space & SessionData::GetOldSpace(long id, SpaceMap & space_map, bool * is_new) { - std::pair res = space_map.insert( std::make_pair(id, PT::Space()) ); + std::pair res = space_map.insert( std::make_pair(id, SpacePair()) ); if( is_new ) *is_new = res.second; -return res.first->second; +return res.first->second.old_space; } +PT::Space & SessionData::GetNewSpace(long id, SpaceMap & space_map, bool * is_new) +{ + std::pair res = space_map.insert( std::make_pair(id, SpacePair()) ); + + if( is_new ) + *is_new = res.second; + +return res.first->second.new_space; +} + } // namespace diff --git a/plugins/ticket/sessiondata.h b/plugins/ticket/sessiondata.h index bc62fac..5b81de9 100755 --- a/plugins/ticket/sessiondata.h +++ b/plugins/ticket/sessiondata.h @@ -28,9 +28,21 @@ struct SessionData : public PluginDataBase SessionData(); ~SessionData(); + struct SpacePair + { + PT::Space new_space; + PT::Space old_space; + + // old_space is used when editing an existing ticket + // current ticket space is copied to old_space + // and when the session expires only new added files + // are deleted + }; + + virtual void Clear(); typedef std::map TicketMap; - typedef std::map SpaceMap; + typedef std::map SpaceMap; // temporary tickets for 'createticket' function @@ -54,21 +66,21 @@ struct SessionData : public PluginDataBase // inserting and returning a new ticket or just returning the ticket if it exists Ticket & GetTicket(long id, TicketMap & ticket_map, bool * is_new = 0); - // inserting and returning a new space or just returning the space if it exists - PT::Space & GetSpace(long id, SpaceMap & space_map, bool * is_new = 0); + // inserting and returning a new/old space or just returning the space if it exists + PT::Space & GetOldSpace(long id, SpaceMap & space_map, bool * is_new = 0); + PT::Space & GetNewSpace(long id, SpaceMap & space_map, bool * is_new = 0); // for deleting files - // !! IMPROVE ME: when the program exits there can be a situation that - // fun_rm was finished and then an object of this class exits and call fun_rm - // so we should guarantee that all sessions object are removed first Fun::Rm * fun_rm; - void RemoveFiles(SpaceMap & space_map); - - private: - void RemoveFiles(PT::Space & space); + void RemoveFiles(SpaceMap & space_map, bool only_stale_files); + void RemoveAllFiles(PT::Space & new_space); + void RemoveAllStaleFiles(PT::Space & new_space, PT::Space & old_space); + + void BuildFileList(std::vector & file_tab, PT::Space & space); + void CheckFile(std::vector & file_tab, PT::Space & space); };