Skip to content

Conversation

@orientlu
Copy link
Contributor

fix read lock nest

fix read lock nest
@orientlu orientlu changed the title #18 fix read lock netst #118 fix read lock netst May 26, 2019
@orientlu
Copy link
Contributor Author

is a bug, i test lorasever project ,found my gateway-bridge will block on handlePackage where try to get the read lock. and i think the block is cause by read lock nest
1.function handlePushData is called by handlePacket which will get the read lock,
2.fucntion handleStats is called by handlePushData and will get the read lock too
here, if somewhere get the write lock betwen 1 and 2, will cause deadlock

@brocaar
Copy link
Collaborator

brocaar commented May 27, 2019

I don't believe this should create a deadlock, as there can be multiple read-locks simultaneously (in contrast to a acquiring a write-lock, which will wait until all other read or write locks are released).

However you're right that there is no need to get a new read-lock in the handleStats function.

@brocaar brocaar merged commit 0112777 into chirpstack:master May 27, 2019
@orientlu
Copy link
Contributor Author

orientlu commented May 27, 2019

I don't believe this should create a deadlock, as there can be multiple read-locks simultaneously (in contrast to a acquiring a write-lock, which will wait until all other read or write locks are released).

However you're right that there is no need to get a new read-lock in the handleStats function.

yes, i totally agree multiple read-locks and acquiring a write-lock which will wait until all other locks are released.
but what i mean is this scene: get multiple read-locks in the sam function call.
the example show what i mean

package main
import "fmt"
import "sync"
import "time"

var testMutex sync.RWMutex

func main() {
	fmt.Println("start")

	go func() {
		testMutex.RLock()
		defer testMutex.RUnlock()
		fmt.Println("get r lock 1")
		time.Sleep(time.Duration(3) * time.Second) // wait write lock

		fmt.Println("try to get r lock 2")
		// block by write lock
                testMutex.RLock()
		fmt.Println("get r lock 2")
		defer testMutex.RUnlock()
	}()

	go func() {
		time.Sleep(time.Duration(1) * time.Second) 
                // get write lock after one read lock had got
		// block by read lock 1
                fmt.Println("try to get w lock")
		testMutex.Lock()
		defer testMutex.Unlock()
		fmt.Println("get w lock")
	}()

	time.Sleep(time.Duration(20) * time.Second)
	fmt.Println("killed")
}

@brocaar
Copy link
Collaborator

brocaar commented May 29, 2019

Sorry, you're right. When it tries to acquire a write-lock between two read-locks then there is indeed a deadlock. Good catch 👍

@orientlu orientlu deleted the fix-rlock-nest branch June 21, 2019 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants