Rewrite to use test_support's fine fcmp instead -- I didn't know that
[python/dscho.git] / Demo / sgi / video / vtime.py
blobc333e57983ec14296495687a444c97a6f87995be
2 # Module vtime - Keep virtual time between two nodes.
4 # We try for synchronised clocks by sending a packet of the for
5 # (1,mytime,0) to the other side, and waiting (at most) a second for
6 # a reply. This reply has the form (2,mytime,histime), and we can
7 # estimate the time difference by defining histime to be exactly half-way
8 # between the time we sent our message and got our reply. We send a
9 # final (3,mynewtime,histime) message to allow the other side to do the
10 # same computations.
12 # Note that the protocol suffers heavily from the 2-army problem.
13 # It'll have to do until I can read up on time-sync protocols, though.
15 from socket import *
16 import time
18 MSGSIZE = 100
19 MSGTIMEOUT = 1000
21 recv_timeout = 'receive timeout'
22 bad_connect = 'Bad connection'
24 def timeavg(a,b):
25 return int((long(a)+b)/2L)
26 def tryrecv(s):
27 cnt = 0
28 while 1:
29 if s.avail():
30 return s.recvfrom(MSGSIZE)
31 time.millisleep(100)
32 cnt = cnt + 100
33 if cnt > MSGTIMEOUT:
34 raise recv_timeout
36 class VTime():
37 def init(self,(client,host,port)):
38 s = socket(AF_INET, SOCK_DGRAM)
39 host = gethostbyname(host)
40 localhost = gethostbyname(gethostname())
41 raddr = (host,port)
42 s.bind((localhost,port))
43 if client:
45 # We loop here because we want the *second* measurement
46 # for accuracy
47 for loopct in (0,2):
48 curtijd = time.millitimer()
49 check = `(loopct,curtijd,0)`
50 s.sendto(check,raddr)
51 while 1:
52 try:
53 if loopct:
54 data, other = s.recvfrom(MSGSIZE)
55 else:
56 data, other = tryrecv(s)
57 newtijd = time.millitimer()
58 if other <> raddr:
59 print 'Someone else syncing to us: ', other
60 raise bad_connect
61 data = eval(data)
62 if data[:2] == (loopct+1,curtijd):
63 break
64 if data[0] <> 2:
65 print 'Illegal sync reply: ', data
66 raise bad_connect
67 except recv_timeout:
68 curtijd = time.millitimer()
69 check = `(loopct,curtijd,0)`
70 s.sendto(check,raddr)
71 histime = data[2]
72 s.sendto(`(4,newtijd,histime)`,raddr)
73 mytime = timeavg(curtijd,newtijd)
74 #mytime = curtijd
75 self.timediff = histime - mytime
76 else:
77 while 1:
78 data,other = s.recvfrom(MSGSIZE)
79 if other <> raddr:
80 print 'Someone else syncing to us: ', other, ' Wanted ', raddr
81 raise bad_connect
82 data = eval(data)
83 if data[0] in (0,2):
84 curtijd = time.millitimer()
85 s.sendto(`(data[0]+1,data[1],curtijd)`,raddr)
86 elif data[0] == 4:
87 newtijd = time.millitimer()
88 histime = data[1]
89 mytime = timeavg(curtijd,newtijd)
90 #mytime = curtijd
91 self.timediff = histime-mytime
92 break
93 else:
94 print 'Funny data: ', data
95 raise bad_connect
96 return self
98 def his2mine(self,tijd):
99 return tijd - self.timediff
101 def mine2his(self, tijd):
102 return tijd + self.timediff
104 def test(clt, host, port):
105 xx = VTime().init(clt,host,port)
106 print 'Time diff: ', xx.his2mine(0)