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  }