+ local task = simgrid.task.new(comp_size, comm_size)
+ task[type] = "get predecessor"
+ task[answer_to] = my_node.id
+
+ if task:send(ask_to, timeout) then
+ -- request successfully sent: wait for an answer
+ while true do
+ task = simgrid.comm.wait(my_node.comm_recv, timeout)
+ my_node.comm_recv = simgrid.task.irecv(my_node.id)
+
+ if not task then
+ -- failed to receive the answer
+ return nil
+ else
+ -- a task was received: is it the expected answer?
+ if task[type] ~= "get predecessor answer" then
+ -- this is not our answer
+ handle_task(task)
+ else
+ -- this is our answer
+ -- FIXME make sure the message answers to this particular request
+ return task[answer]
+ end
+ end
+ end
+ end
+
+ return successor
+end
+
+-- Checks the immediate successor of the current node.
+function stabilize()
+
+ local candidate
+ local successor = my_node.fingers[1]
+ if successor ~= my_node.id then
+ candidate = remote_get_predecessor(successor)
+ else
+ candidate = my_node.predecessor
+ end
+
+ -- this node is a candidate to become my new successor
+ if candidate ~= nil and is_in_interval(candidate, my_node.id + 1, successor -1) then
+ my_node.fingers[1] = candidate
+ end
+
+ if successor ~= my_node.id then
+ remote_notify(successor, my_node.id)
+ end
+end
+
+-- Notifies the current node that its predecessor my have changed
+-- - candidate_predecessor: the possible new predecessor
+function notify(candidate_predecessor)
+
+ if my_node.predecessor == nil or is_in_interval(candidate_predecessor,
+ my_node.predecessor + 1, my_node.id - 1) then
+ my_node.predecessor = candidate_predecessor
+ end
+end
+
+-- Notifies a remote node that its predecessor my have changed.
+-- - notify_to
+-- - candidate the possible new predecessor
+function remote_notify(notify_to, candidate_predecessor)
+
+ local task = simgrid.task.new(comp_size, comm_size)
+ task[type] = "notify"
+ task[request_id] = candidate_predecessor
+ task:dsend(notify_to)
+end
+
+-- Refreshes the finger table of the current node.
+function fix_fingers()
+
+ local i = my_node.next_finger_to_fix
+ local id = find_successor(my_node.id + 2^i)
+ if id ~= nil then
+ if id ~= my_node.fingers[i] then
+ fingers[i] = id