ollie/fs/lifecycle.go

78 lines
1.9 KiB
Go

package fs
import (
"sync"
"ollie/session"
)
// globalRootState is set by NewRoot so handler functions can access
// root state without going through ctx.Root.
var globalRootState *RootState
// RootState holds the root-level state for the 9P filesystem.
type RootState struct {
Cfg Config
// SessionNodes caches the fs-layer wrappers for sessions.
// Keyed by session name (mutable), must be kept in sync with session registry.
nodesMu sync.RWMutex
SessionNodes map[string]*SessionNode
}
// GetOrCreateNode returns the SessionNode for the given session, creating one if needed.
func (rs *RootState) GetOrCreateNode(sess *session.Session) *SessionNode {
rs.nodesMu.RLock()
node, ok := rs.SessionNodes[sess.Name()]
rs.nodesMu.RUnlock()
if ok {
return node
}
rs.nodesMu.Lock()
defer rs.nodesMu.Unlock()
// Double-check after acquiring write lock
if node, ok := rs.SessionNodes[sess.Name()]; ok {
return node
}
node = NewSessionNode(sess)
rs.SessionNodes[sess.Name()] = node
return node
}
// RemoveNode removes the SessionNode for a session.
func (rs *RootState) RemoveNode(name string) {
rs.nodesMu.Lock()
delete(rs.SessionNodes, name)
rs.nodesMu.Unlock()
}
// RenameNode updates the SessionNodes map when a session is renamed.
func (rs *RootState) RenameNode(oldName, newName string) {
rs.nodesMu.Lock()
defer rs.nodesMu.Unlock()
if node, ok := rs.SessionNodes[oldName]; ok {
delete(rs.SessionNodes, oldName)
rs.SessionNodes[newName] = node
}
}
func state(root *Tree) *RootState {
return root.Data.(*RootState)
}
// Shutdown interrupts all sessions, waits for idle, persists, and closes.
func Shutdown(root *Tree) {
session.Shutdown()
}
// InterruptAll interrupts every active session.
func InterruptAll(root *Tree) {
session.InterruptAll()
}
// Lookup returns the session for the given ID, or nil.
func Lookup(root *Tree, id string) *session.Session {
return session.Lookup(id)
}