github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/model/util.go (about) 1 // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). 2 // All rights reserved. Use of this source code is governed by an MIT-style 3 // license that can be found in the LICENSE file. 4 5 package model 6 7 import ( 8 "fmt" 9 "sync" 10 "time" 11 12 "github.com/calmh/syncthing/protocol" 13 ) 14 15 func cmMap(cm protocol.ClusterConfigMessage) map[string]map[protocol.NodeID]uint32 { 16 m := make(map[string]map[protocol.NodeID]uint32) 17 for _, repo := range cm.Repositories { 18 m[repo.ID] = make(map[protocol.NodeID]uint32) 19 for _, node := range repo.Nodes { 20 var id protocol.NodeID 21 copy(id[:], node.ID) 22 m[repo.ID][id] = node.Flags 23 } 24 } 25 return m 26 } 27 28 type ClusterConfigMismatch error 29 30 // compareClusterConfig returns nil for two equivalent configurations, 31 // otherwise a descriptive error 32 func compareClusterConfig(local, remote protocol.ClusterConfigMessage) error { 33 lm := cmMap(local) 34 rm := cmMap(remote) 35 36 for repo, lnodes := range lm { 37 _ = lnodes 38 if rnodes, ok := rm[repo]; ok { 39 for node, lflags := range lnodes { 40 if rflags, ok := rnodes[node]; ok { 41 if lflags&protocol.FlagShareBits != rflags&protocol.FlagShareBits { 42 return ClusterConfigMismatch(fmt.Errorf("remote has different sharing flags for node %q in repository %q", node, repo)) 43 } 44 } 45 } 46 } 47 } 48 49 return nil 50 } 51 52 func deadlockDetect(mut sync.Locker, timeout time.Duration) { 53 go func() { 54 for { 55 time.Sleep(timeout / 4) 56 ok := make(chan bool, 2) 57 58 go func() { 59 mut.Lock() 60 mut.Unlock() 61 ok <- true 62 }() 63 64 go func() { 65 time.Sleep(timeout) 66 ok <- false 67 }() 68 69 if r := <-ok; !r { 70 panic("deadlock detected") 71 } 72 } 73 }() 74 }