forked from qt-creator/qt-creator
CmdBridge: Fix deadlock
The watch mutex was held indefinitely since the "defer" is only called once the parent function exits. Moving the event handling into its own function solves the issue. Also removed unused function "processRemove" Change-Id: I66598d1ba0fb66622ca97531f9ee13272ce63f50 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -35,13 +35,7 @@ type watchevent struct {
|
|||||||
EventType int
|
EventType int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (watchHandler *WatcherHandler) start(out chan<- []byte) {
|
func handleEvent(event fsnotify.Event, watchHandler *WatcherHandler, out chan<- []byte) {
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case event, ok := <-watchHandler.watcher.Events:
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
watchHandler.mutex.Lock()
|
watchHandler.mutex.Lock()
|
||||||
defer watchHandler.mutex.Unlock()
|
defer watchHandler.mutex.Unlock()
|
||||||
|
|
||||||
@@ -69,6 +63,16 @@ func (watchHandler *WatcherHandler) start(out chan<- []byte) {
|
|||||||
out <- data
|
out <- data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (watchHandler *WatcherHandler) start(out chan<- []byte) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event, ok := <-watchHandler.watcher.Events:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handleEvent(event, watchHandler, out)
|
||||||
case err, ok := <-watchHandler.watcher.Errors:
|
case err, ok := <-watchHandler.watcher.Errors:
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@@ -151,29 +155,3 @@ type watchnotfounderror struct {
|
|||||||
func (e *watchnotfounderror) Error() string {
|
func (e *watchnotfounderror) Error() string {
|
||||||
return "Watch not found"
|
return "Watch not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (watchHandler *WatcherHandler) processRemove(cmd command, out chan<- []byte) {
|
|
||||||
watchHandler.mutex.Lock()
|
|
||||||
defer watchHandler.mutex.Unlock()
|
|
||||||
|
|
||||||
if _, ok := watchHandler.watchList[cmd.Id]; !ok {
|
|
||||||
sendError(out, cmd, &watchnotfounderror{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
watchHandler.watchRefs[cmd.Path]--
|
|
||||||
if watchHandler.watchRefs[cmd.Path] == 0 {
|
|
||||||
err := watchHandler.watcher.Remove(cmd.Path)
|
|
||||||
if err != nil {
|
|
||||||
sendError(out, cmd, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(watchHandler.watchList, cmd.Id)
|
|
||||||
|
|
||||||
data, _ := cbor.Marshal(removewatchresult{
|
|
||||||
Type: "removewatchresult",
|
|
||||||
Id: cmd.Id,
|
|
||||||
Result: true,
|
|
||||||
})
|
|
||||||
out <- data
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user