Fix deadlock (#144)

This commit is contained in:
giongto35 2019-11-29 04:00:19 +08:00 committed by GitHub
parent 0b9d628ec2
commit c1b650cac9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 10 deletions

View file

@ -3,6 +3,7 @@ package nanoarch
import (
"image"
"log"
"sync"
"time"
"github.com/giongto35/cloud-game/pkg/config"
@ -59,6 +60,9 @@ type naEmulator struct {
keys []bool
done chan struct{}
// lock to lock uninteruptable operation
lock *sync.Mutex
}
var NAEmulator *naEmulator
@ -78,6 +82,7 @@ func NewNAEmulator(etype string, roomID string, inputChannel <-chan int) (*naEmu
keys: make([]bool, joypadNumKeys),
roomID: roomID,
done: make(chan struct{}, 1),
lock: &sync.Mutex{},
}, imageChannel, audioChannel
}

View file

@ -18,20 +18,16 @@ import "C"
import (
"io/ioutil"
"sync"
)
var saveLock int32
var m sync.Mutex
func (na *naEmulator) GetLock() {
//atomic.CompareAndSwapInt32(&saveLock, 0, 1)
m.Lock()
//atomic.CompareAndSwapInt32(&na.saveLock, 0, 1)
na.lock.Lock()
}
func (na *naEmulator) ReleaseLock() {
//atomic.CompareAndSwapInt32(&saveLock, 1, 0)
m.Unlock()
//atomic.CompareAndSwapInt32(&na.saveLock, 1, 0)
na.lock.Unlock()
}
// Save the current state to the filesystem. name is the name of the

View file

@ -199,6 +199,7 @@ func (r *Room) startWebRTCSession(peerconnection *webrtc.WebRTC, playerIndex int
}
}()
// bug: when inputchannel here = nil , skip and finish
for input := range peerconnection.InputChannel {
// NOTE: when room is no longer running. InputChannel needs to have extra event to go inside the loop
if peerconnection.Done || !peerconnection.IsConnected() || !r.IsRunning {
@ -258,9 +259,16 @@ func (r *Room) Close() {
// Save game before quit. Only save for game which was previous saved to avoid flooding database
if r.isRoomExisted() {
log.Println("Saved Game before closing room")
r.SaveGame()
// use goroutine here because SaveGame attempt to acquire a emulator lock.
// the lock is holding before coming to close, so it will cause deadlock if SaveGame is synchronous
go func() {
// Save before close, so save can have correct state (Not sure) may again cause deadlock
r.SaveGame()
r.director.Close()
}()
} else {
r.director.Close()
}
r.director.Close()
log.Println("Closing input of room ", r.ID)
close(r.inputChannel)
close(r.Done)