78 lines
1.9 KiB
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)
|
|
}
|