Procházet zdrojové kódy

fix: prevent potential deadlock in stdio handler listener invocation (#72)

Modify stdout listener handling to avoid potential deadlocks by:
- Copying listeners before invocation
- Executing listener callbacks outside of the lock
- Separating listener retrieval and execution steps
Yeuoly před 4 měsíci
rodič
revize
cf494208aa

+ 11 - 2
internal/core/plugin_manager/local_runtime/stdio_handle.go

@@ -100,13 +100,22 @@ func (s *stdioHolder) StartStdout(notify_heartbeat func()) {
 				for _, listener := range listeners {
 					listener(s.id, data)
 				}
+				// FIX: avoid deadlock to plugin invoke
 				s.l.Lock()
-				defer s.l.Unlock()
+				tasks := []func(){}
 				for listener_session_id, listener := range s.listener {
+					// copy the listener to avoid reference issue
+					listener := listener
 					if listener_session_id == session_id {
-						listener(data)
+						tasks = append(tasks, func() {
+							listener(data)
+						})
 					}
 				}
+				s.l.Unlock()
+				for _, t := range tasks {
+					t()
+				}
 			},
 			func() {
 				// notify launched