godis icon indicating copy to clipboard operation
godis copied to clipboard

why release lock reverse order in RWUnLocks

Open liamgheng opened this issue 2 years ago • 1 comments

func (dict *ConcurrentDict) RWLocks(writeKeys []string, readKeys []string) {
	keys := append(writeKeys, readKeys...)

        // Lock in normal order
	indices := dict.toLockIndices(keys, false)

	writeIndexSet := make(map[uint32]struct{})
	for _, wKey := range writeKeys {
		idx := dict.spread(fnv32(wKey))
		writeIndexSet[idx] = struct{}{}
	}
	for _, index := range indices {
		_, w := writeIndexSet[index]
		mu := &dict.table[index].mutex
		if w {
			mu.Lock()
		} else {
			mu.RLock()
		}
	}
}

// RWUnLocks unlocks write keys and read keys together. allow duplicate keys
func (dict *ConcurrentDict) RWUnLocks(writeKeys []string, readKeys []string) {
	keys := append(writeKeys, readKeys...)
        // Unlock in reverse order
	indices := dict.toLockIndices(keys, true)
	writeIndexSet := make(map[uint32]struct{})
	for _, wKey := range writeKeys {
		idx := dict.spread(fnv32(wKey))
		writeIndexSet[idx] = struct{}{}
	}
	for _, index := range indices {
		_, w := writeIndexSet[index]
		mu := &dict.table[index].mutex
		if w {
			mu.Unlock()
		} else {
			mu.RUnlock()
		}
	}
}

why release lock reverse order in RWUnLocks? Or If release lock in normal or random order,can cause some race problem?

Thanks

liamgheng avatar Nov 27 '23 23:11 liamgheng

That , Thread 1 locks in the order of A-B,and thread 2 locks in the order of B-A, will cause a deadlock.Therefore, the same order must be used for locking. The reverse order of unlocking and locking is just in case.

HDT3213 avatar Dec 11 '23 06:12 HDT3213