From 9962d68b546cff924336434b14180743086bc2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 9 Aug 2005 16:20:23 +0000 Subject: [PATCH] Now cleanly frees all resources when removed from the cache. Also removes team listeners when the session is deleted. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13923 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_cache/launch_speedup.cpp | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/file_cache/launch_speedup.cpp b/src/add-ons/kernel/file_cache/launch_speedup.cpp index 5b5d517d4a..7f1363394e 100644 --- a/src/add-ons/kernel/file_cache/launch_speedup.cpp +++ b/src/add-ons/kernel/file_cache/launch_speedup.cpp @@ -86,6 +86,9 @@ class Session { void Lock() { mutex_lock(&fLock); } void Unlock() { mutex_unlock(&fLock); } + status_t StartWatchingTeam(); + void StopWatchingTeam(); + status_t LoadFromDirectory(int fd); status_t Save(); void Prefetch(); @@ -107,6 +110,7 @@ class Session { bigtime_t fActiveUntil; bigtime_t fTimestamp; bool fClosing; + bool fIsWatchingTeam; }; class SessionGetter { @@ -250,7 +254,7 @@ start_session(team_id team, mount_id device, vnode_id node, const char *name, if (session == NULL) return NULL; - if (session->InitCheck() != B_OK) { + if (session->InitCheck() != B_OK || session->StartWatchingTeam() != B_OK) { delete session; return NULL; } @@ -367,7 +371,8 @@ Session::Session(team_id team, const char *name, mount_id device, fNodes(NULL), fNodeCount(0), fTeam(team), - fClosing(false) + fClosing(false), + fIsWatchingTeam(false) { if (name != NULL) { size_t length = strlen(name) + 1; @@ -395,7 +400,8 @@ Session::Session(const char *name) : fNodeHash(NULL), fNodes(NULL), - fClosing(false) + fClosing(false), + fIsWatchingTeam(false) { fTeam = -1; fNodeRef.device = -1; @@ -433,6 +439,8 @@ Session::~Session() free(node); } } + + StopWatchingTeam(); } @@ -445,9 +453,6 @@ Session::InitCheck() if (fNodeHash == NULL) return B_NO_MEMORY; - if (Team() >= B_OK && start_watching_team(Team(), team_gone, this) != B_OK) - return B_NO_MEMORY; - return B_OK; } @@ -492,6 +497,28 @@ Session::RemoveNode(mount_id device, vnode_id id) } +status_t +Session::StartWatchingTeam() +{ + if (Team() < B_OK) + return B_OK; + + status_t status = start_watching_team(Team(), team_gone, this); + if (status == B_OK) + fIsWatchingTeam = true; + + return status; +} + + +void +Session::StopWatchingTeam() +{ + if (fIsWatchingTeam) + stop_watching_team(Team(), team_gone, this); +} + + void Session::Prefetch() { @@ -784,7 +811,26 @@ uninit() recursive_lock_lock(&sLock); - // ToDo: free sessions from hash tables + // free all sessions from the hashes + + uint32 cookie = 0; + Session *session; + while ((session = (Session *)hash_remove_first(sTeamHash, &cookie)) != NULL) { + delete session; + } + cookie = 0; + while ((session = (Session *)hash_remove_first(sPrefetchHash, &cookie)) != NULL) { + delete session; + } + + // free all sessions from the main prefetch list + + for (session = sMainPrefetchSessions; session != NULL; ) { + sMainPrefetchSessions = session->Next(); + delete session; + session = sMainPrefetchSessions; + } + hash_uninit(sTeamHash); hash_uninit(sPrefetchHash); recursive_lock_destroy(&sLock);