Stuff happened
[progcomp2013.git] / qchess / src / timeout_player.py
1 import multiprocessing
2
3 # Hacky alternative to using select for timing out players
4
5 # WARNING: Do not wrap around HumanPlayer or things breakify
6 # WARNING: Do not use in general or things breakify
7
8 class Sleeper(multiprocessing.Process):
9         def __init__(self, timeout):
10                 multiprocessing.Process.__init__(self)
11                 self.timeout = timeout
12
13         def run(self):
14                 time.sleep(self.timeout)
15
16
17 class Worker(multiprocessing.Process):
18         def __init__(self, function, args, q):
19                 multiprocessing.Process.__init__(self)
20                 self.function = function
21                 self.args = args
22                 self.q = q
23
24         def run(self):
25                 #print str(self) + " runs " + str(self.function) + " with args " + str(self.args) 
26                 self.q.put(self.function(*self.args))
27                 
28                 
29
30 def TimeoutFunction(function, args, timeout):
31         q = multiprocessing.Queue()
32         w = Worker(function, args, q)
33         s = Sleeper(timeout)
34         w.start()
35         s.start()
36         while True: # Busy loop of crappyness
37                 if not w.is_alive():
38                         s.terminate()
39                         result = q.get()
40                         w.join()
41                         #print "TimeoutFunction gets " + str(result)
42                         return result
43                 elif not s.is_alive():
44                         w.terminate()
45                         s.join()
46                         raise Exception("TIMEOUT")
47
48         
49                 
50
51 # A player that wraps another player and times out its moves
52 # Uses threads
53 # A (crappy) alternative to the use of select()
54 class TimeoutPlayer(Player):
55         def __init__(self, base_player, timeout):
56                 Player.__init__(self, base_player.name, base_player.colour)
57                 self.base_player = base_player
58                 self.timeout = timeout
59                 
60         def select(self):
61                 return TimeoutFunction(self.base_player.select, [], self.timeout)
62                 
63         
64         def get_move(self):
65                 return TimeoutFunction(self.base_player.get_move, [], self.timeout)
66
67         def update(self, result):
68                 return TimeoutFunction(self.base_player.update, [result], self.timeout)
69
70         def quit(self, final_result):
71                 return TimeoutFunction(self.base_player.quit, [final_result], self.timeout)

UCC git Repository :: git.ucc.asn.au