class LocalListener(Thread): def __init__(self, addr, user_list): Thread.__init__(self) self.pipe = PIPE() self.user_list = user_list self.sock = socket.socket() self.sock.bind(addr) self.sock.listen(20) def new_user(self): return self.pipe.read() def connect(self, addr, uid): s = socket.socket() try: uid = uid.ljust(20) s.connect(addr) s.sendall(uid) except: #print 'connect error' return None return s def run(self): while True: conn, addr = self.sock.accept() try: user_id = conn.recv(20) self.user_list[user_id] = conn self.pipe.write(user_id) except: #print 'recv user_id error' continue
class CASTSelecter(Thread): def __init__(self, broadcast): Thread.__init__(self) self.cbpipe = PIPE() self.gbpipe = PIPE() self.abpipe = PIPE() self.b = broadcast def sendCB(self, data, addr=None): time.sleep(0.01) _data = "CBCAST" + data if addr == None: self.b.sendall(_data) else: self.b.send(addr, _data) def sendGB(self, data, addr=None): time.sleep(0.01) _data = "GBCAST" + data if addr == None: self.b.sendall(_data) else: self.b.send(addr, _data) def sendAB(self, data, addr=None): pass def recvCB(self): return self.cbpipe.read() def recvGB(self): return self.gbpipe.read() def recv(self): time.sleep(0.01) _data = self.b.read() header = _data[:6] data = _data[6:] if header == "CBCAST": self.cbpipe.write(data) if header == "GBCAST": self.gbpipe.write(data) def run(self): while True: self.recv()
class CASTSelecter(Thread): def __init__(self, broadcast): Thread.__init__(self) self.cbpipe = PIPE() self.gbpipe = PIPE() self.abpipe = PIPE() self.b = broadcast def sendCB(self, data, addr = None): time.sleep(0.01) _data = "CBCAST" + data if addr == None: self.b.sendall(_data) else: self.b.send(addr, _data) def sendGB(self, data, addr = None): time.sleep(0.01) _data = "GBCAST" + data if addr == None: self.b.sendall(_data) else: self.b.send(addr, _data) def sendAB(self, data, addr = None): pass def recvCB(self): return self.cbpipe.read() def recvGB(self): return self.gbpipe.read() def recv(self): time.sleep(0.01) _data = self.b.read() header = _data[:6] data = _data[6:] if header == "CBCAST": self.cbpipe.write(data) if header == "GBCAST": self.gbpipe.write(data) def run(self): while True: self.recv()
class BroadCast(): def __init__(self): self.output_pipe = PIPE() self.signal_pipe = PIPE() self.mtcp = MTCP(self.output_pipe, self.signal_pipe) self.socks = {} #key=addr, value=socket self.input_pipes = {} #key=addr, value=input_pipes self.sending_lock = threading.Lock() def add_addr(self, addr, sock): if addr in self.socks: #print addr, "already in the socket list" return None# error self.socks[addr] = sock input_pipe = PIPE() self.input_pipes[addr] = input_pipe if (sock == None): return None self.mtcp.new_connect(sock, addr, input_pipe) def remove_addr(self, addr): #This will send the socket.close() if addr not in self.socks: #print addr, "not in the socket list" return False sock = self.socks[addr] input_pipe = self.input_pipes[addr] sock.close() input_pipe.close() self.mtcp.close(addr) self.socks[addr] = None self.input_pipes[addr] = None del self.socks[addr] del self.input_pipes[addr] return True def get_addrs(self): return self.socks.keys() def get_sock(self, addr): if addr not in self.socks: return None return self.socks[addr] def get_pipe(self, addr): if addr not in self.input_pipes: return None return self.input_pipes[addr] def read(self): return self.output_pipe.read() def send(self, addr, message): #return the input_pipe self.sending_lock.acquire() try: if self.socks[addr] == None: self.output_pipe.write(message) self.sending_lock.release() return self.output_pipe if addr not in self.input_pipes: #print addr, "not in input_pipe" self.sending_lock.release() return None input_pipe = self.input_pipes[addr] input_pipe.write(message) except: print 'sending error' self.sending_lock.release() return None def sendall(self,message): return self.broadcast(message) def broadcast(self, message): #return how many message has been sent self.sending_lock.acquire() #print 'start to broadcast' for addr in self.input_pipes.keys(): #print 'pipe selection' pipe = self.input_pipes[addr] #print 'end of pipe selection' if (self.socks[addr] == None): #print 'write to locol' self.output_pipe.write(message) #print 'write locol succ' else: try: #print 'pipe write' pipe.write(message) #print 'pipe write succ' except: self.sending_lock.release() self.remove_addr(addr) self.sending_lock.release() #print 'end of broadcast' return len(self.input_pipes) def get_signal_message(self): return self.signal_pipe.read()
t_signal.start() t_output.start() t1 = TSTCP(s, addr, input_pipe, signal_pipe) t1.setDaemon(True) t1.start() t2 = TRTCP(s, addr, output_pipe, signal_pipe) t2.setDaemon(True) t2.start() while True: message = raw_input("") if (message == "q"): break input_pipe.write(message) s.close() if sys.argv[1] == "server_c": #chatting server class forward_pipe(Thread): def __init__(self, src, dst): Thread.__init__(self) self.dst = dst self.src = src def run(self): while True: data = self.src.read() for each_dst in self.dst: each_dst.write(data) signal_pipe = PIPE()
class BroadCast(): def __init__(self): self.output_pipe = PIPE() self.signal_pipe = PIPE() self.mtcp = MTCP(self.output_pipe, self.signal_pipe) self.socks = {} #key=addr, value=socket self.input_pipes = {} #key=addr, value=input_pipes self.sending_lock = threading.Lock() def add_addr(self, addr, sock): if addr in self.socks: #print addr, "already in the socket list" return None # error self.socks[addr] = sock input_pipe = PIPE() self.input_pipes[addr] = input_pipe if (sock == None): return None self.mtcp.new_connect(sock, addr, input_pipe) def remove_addr(self, addr): #This will send the socket.close() if addr not in self.socks: #print addr, "not in the socket list" return False sock = self.socks[addr] input_pipe = self.input_pipes[addr] sock.close() input_pipe.close() self.mtcp.close(addr) self.socks[addr] = None self.input_pipes[addr] = None del self.socks[addr] del self.input_pipes[addr] return True def get_addrs(self): return self.socks.keys() def get_sock(self, addr): if addr not in self.socks: return None return self.socks[addr] def get_pipe(self, addr): if addr not in self.input_pipes: return None return self.input_pipes[addr] def read(self): return self.output_pipe.read() def send(self, addr, message): #return the input_pipe self.sending_lock.acquire() if self.socks[addr] == None: self.output_pipe.write(message) self.sending_lock.release() return self.output_pipe if addr not in self.input_pipes: #print addr, "not in input_pipe" self.sending_lock.release() return None input_pipe = self.input_pipes[addr] input_pipe.write(message) self.sending_lock.release() return input_pipe def sendall(self, message): return self.broadcast(message) def broadcast(self, message): #return how many message has been sent self.sending_lock.acquire() #print 'start to broadcast' for addr in self.input_pipes.keys(): #print 'pipe selection' pipe = self.input_pipes[addr] #print 'end of pipe selection' if (self.socks[addr] == None): #print 'write to locol' self.output_pipe.write(message) #print 'write locol succ' else: try: #print 'pipe write' pipe.write(message) #print 'pipe write succ' except: self.sending_lock.release() self.remove_addr(addr) self.sending_lock.release() #print 'end of broadcast' return len(self.input_pipes) def get_signal_message(self): return self.signal_pipe.read()
class ABCASTManager(object): """Manager for sending ABCAST""" def __init__(self, userId, castSelector, clientManager, logManager): super(ABCASTManager, self).__init__() self.clock = 0 self.clockMutex = threading.Lock() self.logManager = logManager self.userId = userId self.inputPipe = PIPE() self.outputPipe = PIPE() self.castManager = castSelector self.responseReceiver = {} self.receiverMutex = threading.Lock() self.clientList = clientManager.fetch_user_list() self.clientListMutex = threading.Lock() self.clientManager = clientManager self.processQueue = Heap() self.heapMutex = threading.Lock() self.recvProc = CustomThread(self._startReceiveMessage) self.sendProc = CustomThread(self._startSendBroadCast) self.pauseFlag = False self.startFlag = False self.waitCondition = threading.Condition() def start(self): self.recvProc.setDaemon(True) self.sendProc.setDaemon(True) self.recvProc.start() self.sendProc.start() self.startFlag = True def read(self): #parsed value return self.outputPipe.read() def write(self, message): self.inputPipe.write(message) #for CT def block(self): self.pauseFlag = True def waitAllDone(self): if not self.processQueue.empty() or len(self.responseReceiver) > 0: self.waitCondition.acquire() self.waitCondition.wait() self.waitCondition.release() return True def resume(self): self.pauseFlag = False if not self.sendProc.isAlive(): self.sendProc = CustomThread(self._startSendBroadCast) self.sendProc.setDaemon(True) self.sendProc.start() def synchronize(self, operationList): for op in operationList: self.outputPipe.write(op) def addUser(self, userId): self.clientListMutex.acquire() self.clientList = self.clientManager.fetch_user_list() self.clientListMutex.release() def removeUser(self, userId): # print 'ABCASTManager remove user' self.receiverMutex.acquire() for (k, v) in self.responseReceiver.items(): cList = v[0] lastObj = v[1] if userId in cList: cList.remove(userId) if len(cList) == 0: if not lastObj is None: self._sendMessageObjBroadCast(MessageObj(self.userId, None, lastObj.oid, lastObj.mid, self.clientManager.view_id, 'F')) del self.responseReceiver[msgObj.uniqueId()] self.receiverMutex.release() self.clientListMutex.acquire() # print 'fetch user list from user manager' self.clientList = self.clientManager.fetch_user_list() self.clientListMutex.release() # print self.clientList def restoreData(self, userId, msgList): self.heapMutex.acquire() for pair in msgList: msgKey = userId + '_' + str(pair[0]) if pair[1] >= 0: self.processQueue.update(msgKey, pair[1]) else: for obj in self.processQueue.getAllObjects(): if obj.uniqueId() == msgKey: obj.discard = True break self.heapMutex.release() #block thread def _startReceiveMessage(self): while True: # print 'receiving msg' msg = self.castManager.recvCB() # print 'msg received' # print self.clientList msgObj = fromStr(msg) if msgObj.vid != self.clientManager.view_id: continue #selector #for A:: if msgObj.type == 'A': # print '%s receive A-Msg %s' % (self.userId, msg) # self.clientListMutex.acquire() if msgObj.sender in self.clientList: self.heapMutex.acquire() self.processQueue.push(msgObj) self.logManager.insertPrepare(msgObj.sender, msgObj.oid) self.clockMutex.acquire() clk = self.clock = max(self.clock, self.processQueue.maxObj.mid) + 1 self.clockMutex.release() self.heapMutex.release() obj = MessageObj(msgObj.sender, None, msgObj.oid, clk, self.clientManager.view_id, 'P') obj.replier = self.userId self._sendMessageObjBroadCast(obj, msgObj.sender) # print 'P msg sent' # self.clientListMutex.release() elif msgObj.type == 'P': #for P:: # print '%s receive P-Msg %s' % (self.userId, msg) self.receiverMutex.acquire() if msgObj.uniqueId() in self.responseReceiver: cList, lastObj = self.responseReceiver[msgObj.uniqueId()] # print '%s wait for %s, %d left' % (self.userId, msgObj.uniqueId(), len(cList)) # print cList if msgObj.replier in cList: cList.remove(msgObj.replier) if not lastObj or lastObj.smallerThan(msgObj): self.responseReceiver[msgObj.uniqueId()] = (cList, msgObj) lastObj = msgObj if len(cList) == 0: self._sendMessageObjBroadCast(MessageObj(self.userId, None, lastObj.oid, lastObj.mid, self.clientManager.view_id, 'F')) del self.responseReceiver[msgObj.uniqueId()] self.receiverMutex.release() #for F:: else: # print '%s receive F-Msg %s' % (self.userId, msg) self.clientListMutex.acquire() if msgObj.sender in self.clientList: self.heapMutex.acquire() self.processQueue.update(msgObj.uniqueId(), msgObj.mid) self.logManager.updatePrepare(msgObj.sender, msgObj.oid, msgObj.mid) # print '%s is ready: %s' % (self.processQueue.top().uniqueId(), self.processQueue.top().delivered) while not self.processQueue.empty() and self.processQueue.top().delivered and not self.processQueue.top().discard: poppedObj = self.processQueue.pop() # print poppedObj.content if not poppedObj.discard: self.outputPipe.write(poppedObj.content) self.logManager.appendRecord(poppedObj.content) if self.processQueue.empty() and len(self.responseReceiver) == 0: self.waitCondition.acquire() self.waitCondition.notify() self.waitCondition.release() self.heapMutex.release() self.clientListMutex.release() #No lock allowed for this call if A::msg def _sendMessageObjBroadCast(self, msgObj, target=None): if msgObj.type == 'A': #are these locks neccessary? self.receiverMutex.acquire() # self.clientListMutex.acquire() clist = copy.deepcopy(self.clientList) # self.clientListMutex.release() self.responseReceiver[msgObj.uniqueId()] = (clist, None) self.receiverMutex.release() if target is None: # print 'msg sent' # print self.clientList self.castManager.sendCB(str(msgObj)) else: self.castManager.sendCB(str(msgObj), target) #block thread def _startSendBroadCast(self): while not self.pauseFlag: msg = self.inputPipe.read() self.clockMutex.acquire() self.clock += 1 msgObj = MessageObj(self.userId, msg, self.clock, self.clock, self.clientManager.view_id, 'A') self.clockMutex.release() self._sendMessageObjBroadCast(msgObj)
t_signal.start() t_output.start() t1 = TSTCP(s, addr, input_pipe, signal_pipe) t1.setDaemon(True) t1.start() t2 = TRTCP(s, addr, output_pipe, signal_pipe) t2.setDaemon(True) t2.start() while True: message = raw_input("") if (message == "q"): break input_pipe.write(message) s.close() if sys.argv[1] == "server_c": #chatting server class forward_pipe(Thread): def __init__(self, src, dst): Thread.__init__(self) self.dst = dst self.src = src def run(self): while True: data = self.src.read() for each_dst in self.dst: each_dst.write(data)