#!/usr/contrib/bin/agent
include control/do
include control/thread
include control/timing
include econ/usebank
proc refund-2 {thread} {
Zrestore $thread complaint
agent_send $a [list refund $thread [splt $amt]]
agent_send $b [list refund $thread [splt $amt]]
Zdestroy $thread}
proc refund {x thread} {
Zrestore $thread complaint
agent_send $x [list refund $thread [splt $amt]]
Zdestroy $thread}
proc other {a b x} {if {$x==$a} {return $b} {return $a}}
proc arbiter {name maker cash lifetime} {
agent_name $name
require wall $lifetime
agent_event $maker arbiter $cash
init_bank $cash
Zattach
do {
{"STOP"} {
agent_send $maker 0 DONE
agent_end
exit 0
}
{"new %s %s %s %s %s" acash timeout b deal n} {
set thread [Zrestore]
set amt [amt $acash]
mrg $acash
set a $sender
agent_send $b [list arbiter_request $a $amt $timeout $deal $thread]
Zstore accept}
{"accept %s %s" thread bcash} {
Zrestore $thread accept
if {[amt $bcash]!=$amt} {error "amt mismatch [amt $bcash] $amt"}
mrg $bcash
set timer [Tafter $timeout "refund-2 $thread"]
agent_send $a "arbiter_ok $thread $n"
Zstore complaint}
{"no_complaint %s %s" thread who} {
Zrestore $thread complaint
if {[info exists no_complaint]} {hop no_complaint-2}
agent_send [other $a $b $who] "arbiter_no_complaint $thread"
set no_complaint $who}
no_complaint-2 {
Tcancel $timer
refund-2 [Zstore complaint]}
{"complaint %s %s" thread who} {
Zrestore $thread complaint
Tcancel $timer
agent_send [other $a $b $who] "arbiter_complaint $thread"
if {[info exists complaint]} {hop complaint-2}
set timer [Tafter $timeout {refund $who $thread}]
set complaint $who}
complaint-2 {
Zdestroy $thread}
error "amt mismatch" {
agent_send $b [list arbiter_error badcash $thread $bcash]
refund $a [Zstore complaint]}
error "thread nonexistant" {
agent_send $sender "don't mess with me"}
error "thread locked" {
agent_send $sender "arbiter_error outoforder $thread"}
error {"unexpected message %s" msg} {
agent_send $sender "what in hell does this mean? $msg"}}
}