3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00

relay: attempt to fix race conditions in getRemoteUser calls (#92)

This commit is contained in:
James Lu 2015-08-14 08:52:09 -07:00
parent 13e4baba8b
commit 65b8c9db8a

View File

@ -16,7 +16,9 @@ dbname = "pylinkrelay"
if confname != 'pylink': if confname != 'pylink':
dbname += '-%s' % confname dbname += '-%s' % confname
dbname += '.db' dbname += '.db'
relayusers = defaultdict(dict) relayusers = defaultdict(dict)
spawnlocks = defaultdict(threading.Lock)
def relayWhoisHandlers(irc, target): def relayWhoisHandlers(irc, target):
user = irc.users[target] user = irc.users[target]
@ -124,30 +126,31 @@ def getRemoteUser(irc, remoteirc, user, spawnIfMissing=True):
return remoteirc.pseudoclient.uid return remoteirc.pseudoclient.uid
except AttributeError: # Network hasn't been initialized yet? except AttributeError: # Network hasn't been initialized yet?
pass pass
try: with spawnlocks[irc.name]:
u = relayusers[(irc.name, user)][remoteirc.name] try:
except KeyError: u = relayusers[(irc.name, user)][remoteirc.name]
userobj = irc.users.get(user) except KeyError:
if userobj is None or (not spawnIfMissing) or (not remoteirc.connected.is_set()): userobj = irc.users.get(user)
# The query wasn't actually a valid user, or the network hasn't if userobj is None or (not spawnIfMissing) or (not remoteirc.connected.is_set()):
# been connected yet... Oh well! # The query wasn't actually a valid user, or the network hasn't
return # been connected yet... Oh well!
nick = normalizeNick(remoteirc, irc.name, userobj.nick) return
# Truncate idents at 10 characters, because TS6 won't like them otherwise! nick = normalizeNick(remoteirc, irc.name, userobj.nick)
ident = userobj.ident[:10] # Truncate idents at 10 characters, because TS6 won't like them otherwise!
# Ditto hostname at 64 chars. ident = userobj.ident[:10]
host = userobj.host[:64] # Ditto hostname at 64 chars.
realname = userobj.realname host = userobj.host[:64]
modes = getSupportedUmodes(irc, remoteirc, userobj.modes) realname = userobj.realname
u = remoteirc.proto.spawnClient(remoteirc, nick, ident=ident, modes = getSupportedUmodes(irc, remoteirc, userobj.modes)
host=host, realname=realname, u = remoteirc.proto.spawnClient(remoteirc, nick, ident=ident,
modes=modes, ts=userobj.ts).uid host=host, realname=realname,
remoteirc.users[u].remote = irc.name modes=modes, ts=userobj.ts).uid
away = userobj.away remoteirc.users[u].remote = irc.name
if away: away = userobj.away
remoteirc.proto.awayClient(remoteirc, u, away) if away:
relayusers[(irc.name, user)][remoteirc.name] = u remoteirc.proto.awayClient(remoteirc, u, away)
return u relayusers[(irc.name, user)][remoteirc.name] = u
return u
def getLocalUser(irc, user, targetirc=None): def getLocalUser(irc, user, targetirc=None):
"""<irc object> <pseudoclient uid> [<target irc object>] """<irc object> <pseudoclient uid> [<target irc object>]