Lock ordering: conn.lock > cm.lock (conn.lock is outer, cm.lock is inner) CRITICAL: Methods that hold cm.lock must NEVER call into SSHConn (deadlock - violates ordering). Methods called from SSHConn while conn.lock is held should avoid acquiring cm.lock (keep locking simple).
| 18 | // CRITICAL: Methods that hold cm.lock must NEVER call into SSHConn (deadlock - violates ordering). |
| 19 | // Methods called from SSHConn while conn.lock is held should avoid acquiring cm.lock (keep locking simple). |
| 20 | type ConnMonitor struct { |
| 21 | lock *sync.Mutex |
| 22 | Conn *SSHConn // always non-nil, set at creation |
| 23 | Client *ssh.Client // always non-nil, set at creation |
| 24 | LastActivityTime atomic.Int64 |
| 25 | LastInputTime atomic.Int64 |
| 26 | KeepAliveSentTime atomic.Int64 |
| 27 | KeepAliveInFlight bool |
| 28 | ctx context.Context |
| 29 | cancelFunc context.CancelFunc |
| 30 | inputNotifyCh chan int64 |
| 31 | } |
| 32 | |
| 33 | func MakeConnMonitor(conn *SSHConn, client *ssh.Client) *ConnMonitor { |
| 34 | if conn == nil { |
nothing calls this directly
no outgoing calls
no test coverage detected