Server locks rooms when sending states now to prevent exceptions

This commit is contained in:
Uriziel 2013-01-01 13:01:34 +01:00
parent 2941cd1849
commit da94607885

View File

@ -7,6 +7,7 @@ import syncplay
from syncplay.protocols import SyncServerProtocol from syncplay.protocols import SyncServerProtocol
import time import time
from syncplay import constants from syncplay import constants
import threading
class SyncFactory(Factory): class SyncFactory(Factory):
def __init__(self, password = ''): def __init__(self, password = ''):
@ -16,12 +17,14 @@ class SyncFactory(Factory):
self.password = password self.password = password
self._rooms = {} self._rooms = {}
self._roomStates = {} self._roomStates = {}
self._roomUpdate = threading.RLock()
def buildProtocol(self, addr): def buildProtocol(self, addr):
return SyncServerProtocol(self) return SyncServerProtocol(self)
def _createRoomIfDoesntExist(self, roomName): def _createRoomIfDoesntExist(self, roomName):
if (not self._rooms.has_key(roomName)): if (not self._rooms.has_key(roomName)):
with self._roomUpdate:
self._rooms[roomName] = {} self._rooms[roomName] = {}
self._roomStates[roomName] = { self._roomStates[roomName] = {
"position": 0.0, "position": 0.0,
@ -39,6 +42,7 @@ class SyncFactory(Factory):
username += '_' username += '_'
self._createRoomIfDoesntExist(roomName) self._createRoomIfDoesntExist(roomName)
watcher = Watcher(self, watcherProtocol, username, roomName) watcher = Watcher(self, watcherProtocol, username, roomName)
with self._roomUpdate:
self._rooms[roomName][watcherProtocol] = watcher self._rooms[roomName][watcherProtocol] = watcher
print "{0}({2}) connected to room '{1}'".format(username, roomName, watcherProtocol.transport.getPeer().host) print "{0}({2}) connected to room '{1}'".format(username, roomName, watcherProtocol.transport.getPeer().host)
reactor.callLater(0.1, watcher.scheduleSendState) reactor.callLater(0.1, watcher.scheduleSendState)
@ -50,7 +54,7 @@ class SyncFactory(Factory):
if(room.has_key(watcherProtocol)): if(room.has_key(watcherProtocol)):
return room[watcherProtocol] return room[watcherProtocol]
def getAllWatchers(self, watcherProtocol): def getAllWatchers(self, watcherProtocol): #TODO: Optimize me
watchers = {} watchers = {}
for room in self._rooms.itervalues(): for room in self._rooms.itervalues():
for watcher in room.itervalues(): for watcher in room.itervalues():
@ -59,12 +63,14 @@ class SyncFactory(Factory):
def _removeWatcherFromTheRoom(self, watcherProtocol): def _removeWatcherFromTheRoom(self, watcherProtocol):
for room in self._rooms.itervalues(): for room in self._rooms.itervalues():
with self._roomUpdate:
watcher = room.pop(watcherProtocol, None) watcher = room.pop(watcherProtocol, None)
if(watcher): if(watcher):
return watcher return watcher
def _deleteRoomIfEmpty(self, room): def _deleteRoomIfEmpty(self, room):
if (self._rooms[room] == {}): if (self._rooms[room] == {}):
with self._roomUpdate:
self._rooms.pop(room) self._rooms.pop(room)
self._roomStates.pop(room) self._roomStates.pop(room)
@ -160,6 +166,7 @@ class SyncFactory(Factory):
watcher.resetStateTimer() watcher.resetStateTimer()
oldRoom = watcher.room oldRoom = watcher.room
self._createRoomIfDoesntExist(room) self._createRoomIfDoesntExist(room)
with self._roomUpdate:
self._rooms[room][watcherProtocol] = watcher self._rooms[room][watcherProtocol] = watcher
self._roomStates[room]["position"] = watcher.position self._roomStates[room]["position"] = watcher.position
self._roomStates[room]["setBy"] = watcher.name self._roomStates[room]["setBy"] = watcher.name
@ -178,10 +185,12 @@ class SyncFactory(Factory):
def broadcastRoom(self, sender, what): def broadcastRoom(self, sender, what):
room = self._rooms[self.watcherGetRoom(sender)] room = self._rooms[self.watcherGetRoom(sender)]
if(room): if(room):
with self._roomUpdate:
for receiver in room: for receiver in room:
what(receiver) what(receiver)
def broadcast(self, sender, what): def broadcast(self, sender, what):
with self._roomUpdate:
for room in self._rooms.itervalues(): for room in self._rooms.itervalues():
for receiver in room: for receiver in room:
what(receiver) what(receiver)