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 ; i
session = &(*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);
};