AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
raw
history blame
55.3 kB
<html><!-- Created using the cpp_pretty_printer from the dlib C++ library. See http://dlib.net for updates. --><head><title>dlib C++ Library - bsp.cpp</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2012 Davis E. King (davis@dlib.net)
</font><font color='#009900'>// License: Boost Software License See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_BSP_CPph_
<font color='#0000FF'>#define</font> DLIB_BSP_CPph_
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='bsp.h.html'>bsp.h</a>"
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>memory<font color='#5555FF'>&gt;</font>
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>stack<font color='#5555FF'>&gt;</font>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'>namespace</font> dlib
<b>{</b>
<font color='#0000FF'>namespace</font> impl1
<b>{</b>
<font color='#0000FF'><u>void</u></font> <b><a name='connect_all'></a>connect_all</b> <font face='Lucida Console'>(</font>
map_id_to_con<font color='#5555FF'>&amp;</font> cons,
<font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>network_address<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> hosts,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> node_id
<font face='Lucida Console'>)</font>
<b>{</b>
cons.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> hosts.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
<b>{</b>
std::unique_ptr<font color='#5555FF'>&lt;</font>bsp_con<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>con</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> <font color='#BB00BB'>bsp_con</font><font face='Lucida Console'>(</font>hosts[i]<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
dlib::<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>node_id, con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>; <font color='#009900'>// tell the other end our node_id
</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> id <font color='#5555FF'>=</font> i<font color='#5555FF'>+</font><font color='#979000'>1</font>;
cons.<font color='#BB00BB'>add</font><font face='Lucida Console'>(</font>id, con<font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#0000FF'><u>void</u></font> <b><a name='connect_all_hostinfo'></a>connect_all_hostinfo</b> <font face='Lucida Console'>(</font>
map_id_to_con<font color='#5555FF'>&amp;</font> cons,
<font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>hostinfo<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> hosts,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> node_id,
std::string<font color='#5555FF'>&amp;</font> error_string
<font face='Lucida Console'>)</font>
<b>{</b>
cons.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> hosts.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>try</font>
<b>{</b>
std::unique_ptr<font color='#5555FF'>&lt;</font>bsp_con<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>con</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> <font color='#BB00BB'>bsp_con</font><font face='Lucida Console'>(</font>hosts[i].addr<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
dlib::<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>node_id, con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>; <font color='#009900'>// tell the other end our node_id
</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> id <font color='#5555FF'>=</font> hosts[i].node_id;
cons.<font color='#BB00BB'>add</font><font face='Lucida Console'>(</font>id, con<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>std::exception<font color='#5555FF'>&amp;</font><font face='Lucida Console'>)</font>
<b>{</b>
std::ostringstream sout;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Could not connect to </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> hosts[i].addr;
error_string <font color='#5555FF'>=</font> sout.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>break</font>;
<b>}</b>
<b>}</b>
<b>}</b>
<font color='#0000FF'><u>void</u></font> <b><a name='send_out_connection_orders'></a>send_out_connection_orders</b> <font face='Lucida Console'>(</font>
map_id_to_con<font color='#5555FF'>&amp;</font> cons,
<font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>network_address<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> hosts
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// tell everyone their node ids
</font> cons.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>cons.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
dlib::<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>key</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>// now tell them who to connect to
</font> std::vector<font color='#5555FF'>&lt;</font>hostinfo<font color='#5555FF'>&gt;</font> targets;
<font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> hosts.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
<b>{</b>
hostinfo <font color='#BB00BB'>info</font><font face='Lucida Console'>(</font>hosts[i], i<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
dlib::<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>targets, cons[info.node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
targets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>info<font face='Lucida Console'>)</font>;
<font color='#009900'>// let the other host know how many incoming connections to expect
</font> <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> num <font color='#5555FF'>=</font> hosts.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>targets.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
dlib::<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>num, cons[info.node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
cons[info.node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#009900'>// ------------------------------------------------------------------------------------
</font>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'>namespace</font> impl2
<b>{</b>
<font color='#009900'>// These control bytes are sent before each message between nodes. Note that many
</font> <font color='#009900'>// of these are only sent between the control node (node 0) and the other nodes.
</font> <font color='#009900'>// This is because the controller node is responsible for handling the
</font> <font color='#009900'>// synchronization that needs to happen when all nodes block on calls to
</font> <font color='#009900'>// receive_data()
</font> <font color='#009900'>// at the same time.
</font>
<font color='#009900'>// denotes a normal content message.
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> MESSAGE_HEADER <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
<font color='#009900'>// sent to the controller node when someone receives a message via receive_data().
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> GOT_MESSAGE <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
<font color='#009900'>// sent to the controller node when someone sends a message via send().
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> SENT_MESSAGE <font color='#5555FF'>=</font> <font color='#979000'>2</font>;
<font color='#009900'>// sent to the controller node when someone enters a call to receive_data()
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> IN_WAITING_STATE <font color='#5555FF'>=</font> <font color='#979000'>3</font>;
<font color='#009900'>// broadcast when a node terminates itself.
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> NODE_TERMINATE <font color='#5555FF'>=</font> <font color='#979000'>5</font>;
<font color='#009900'>// broadcast by the controller node when it determines that all nodes are blocked
</font> <font color='#009900'>// on calls to receive_data() and there aren't any messages in flight. This is also
</font> <font color='#009900'>// what makes us go to the next epoch.
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> SEE_ALL_IN_WAITING_STATE <font color='#5555FF'>=</font> <font color='#979000'>6</font>;
<font color='#009900'>// This isn't ever transmitted between nodes. It is used internally to indicate
</font> <font color='#009900'>// that an error occurred.
</font> <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>char</u></font> READ_ERROR <font color='#5555FF'>=</font> <font color='#979000'>7</font>;
<font color='#009900'>// ------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>void</u></font> <b><a name='read_thread'></a>read_thread</b> <font face='Lucida Console'>(</font>
impl1::bsp_con<font color='#5555FF'>*</font> con,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> node_id,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> sender_id,
impl1::thread_safe_message_queue<font color='#5555FF'>&amp;</font> msg_buffer
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>try</font>
<b>{</b>
<font color='#0000FF'>while</font><font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
<b>{</b>
impl1::msg_data msg;
<font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>msg.msg_type, con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
msg.sender_id <font color='#5555FF'>=</font> sender_id;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> MESSAGE_HEADER<font face='Lucida Console'>)</font>
<b>{</b>
msg.data.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>)</font>;
<font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>msg.epoch, con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>msg.data, con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
<b>}</b>
msg_buffer.<font color='#BB00BB'>push_and_consume</font><font face='Lucida Console'>(</font>msg<font face='Lucida Console'>)</font>;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> NODE_TERMINATE<font face='Lucida Console'>)</font>
<font color='#0000FF'>break</font>;
<b>}</b>
<b>}</b>
<font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>std::exception<font color='#5555FF'>&amp;</font> e<font face='Lucida Console'>)</font>
<b>{</b>
impl1::msg_data msg;
msg.data.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>)</font>;
vectorstream <font color='#BB00BB'>sout</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>msg.data<font face='Lucida Console'>)</font>;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>An exception was thrown while attempting to receive a message from processing node </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> sender_id <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n</font>";
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Sending processing node address: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_foreign_ip</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>:</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_foreign_port</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Receiving processing node address: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_local_ip</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>:</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_local_port</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Receiving processing node id: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> node_id <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Error message in the exception: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> e.<font color='#BB00BB'>what</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
msg.sender_id <font color='#5555FF'>=</font> sender_id;
msg.msg_type <font color='#5555FF'>=</font> READ_ERROR;
msg_buffer.<font color='#BB00BB'>push_and_consume</font><font face='Lucida Console'>(</font>msg<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#0000FF'>catch</font> <font face='Lucida Console'>(</font>...<font face='Lucida Console'>)</font>
<b>{</b>
impl1::msg_data msg;
msg.data.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>)</font>;
vectorstream <font color='#BB00BB'>sout</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>msg.data<font face='Lucida Console'>)</font>;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>An exception was thrown while attempting to receive a message from processing node </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> sender_id <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n</font>";
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Sending processing node address: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_foreign_ip</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>:</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_foreign_port</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Receiving processing node address: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_local_ip</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>:</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>get_local_port</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> Receiving processing node id: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> node_id <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> std::endl;
msg.sender_id <font color='#5555FF'>=</font> sender_id;
msg.msg_type <font color='#5555FF'>=</font> READ_ERROR;
msg_buffer.<font color='#BB00BB'>push_and_consume</font><font face='Lucida Console'>(</font>msg<font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#009900'>// ------------------------------------------------------------------------------------
</font>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// IMPLEMENTATION OF bsp_context OBJECT MEMBERS
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>void</u></font> bsp_context::
<b><a name='close_all_connections_gracefully'></a>close_all_connections_gracefully</b><font face='Lucida Console'>(</font>
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
_cons.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>_cons.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// tell the other end that we are intentionally dropping the connection
</font> <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>impl2::NODE_TERMINATE,_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
impl1::msg_data msg;
<font color='#009900'>// now wait for all the other nodes to terminate
</font> <font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>num_terminated_nodes <font color='#5555FF'>&lt;</font> _cons.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> num_waiting_nodes <font color='#5555FF'>+</font> num_terminated_nodes <font color='#5555FF'>=</font><font color='#5555FF'>=</font> _cons.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> outstanding_messages <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
num_waiting_nodes <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
<font color='#BB00BB'>broadcast_byte</font><font face='Lucida Console'>(</font>impl2::SEE_ALL_IN_WAITING_STATE<font face='Lucida Console'>)</font>;
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>current_epoch;
<b>}</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font>msg_buffer.<font color='#BB00BB'>pop</font><font face='Lucida Console'>(</font>msg<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Error reading from msg_buffer in dlib::bsp_context.</font>"<font face='Lucida Console'>)</font>;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::NODE_TERMINATE<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>num_terminated_nodes;
_cons[msg.sender_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>terminated <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
<b>}</b>
<font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::READ_ERROR<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>msg.<font color='#BB00BB'>data_to_string</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::MESSAGE_HEADER<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>A BSP node received a message after it has terminated.</font>"<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::GOT_MESSAGE<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#5555FF'>-</font><font color='#5555FF'>-</font>num_waiting_nodes;
<font color='#5555FF'>-</font><font color='#5555FF'>-</font>outstanding_messages;
<b>}</b>
<font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::SENT_MESSAGE<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>outstanding_messages;
<b>}</b>
<font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>msg.msg_type <font color='#5555FF'>=</font><font color='#5555FF'>=</font> impl2::IN_WAITING_STATE<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>num_waiting_nodes;
<b>}</b>
<b>}</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
_cons.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>_cons.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// tell the other end that we are intentionally dropping the connection
</font> <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>impl2::NODE_TERMINATE,_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>outstanding_messages <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
std::ostringstream sout;
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>A BSP job was allowed to terminate before all sent messages have been received.\n</font>";
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>There are at least </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> outstanding_messages <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> messages still in flight. Make sure all sent messages\n</font>";
sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>have a corresponding call to receive().</font>";
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>sout.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
bsp_context::
~<b><a name='bsp_context'></a>bsp_context</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
<b>{</b>
_cons.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>_cons.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>con<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>shutdown</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
msg_buffer.<font color='#BB00BB'>disable</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#009900'>// this will wait for all the threads to terminate
</font> threads.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
bsp_context::
<b><a name='bsp_context'></a>bsp_context</b><font face='Lucida Console'>(</font>
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> node_id_,
impl1::map_id_to_con<font color='#5555FF'>&amp;</font> cons_
<font face='Lucida Console'>)</font> :
outstanding_messages<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>,
num_waiting_nodes<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>,
num_terminated_nodes<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>,
current_epoch<font face='Lucida Console'>(</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>,
_cons<font face='Lucida Console'>(</font>cons_<font face='Lucida Console'>)</font>,
_node_id<font face='Lucida Console'>(</font>node_id_<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// spawn a bunch of read threads, one for each connection
</font> _cons.<font color='#BB00BB'>reset</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font>_cons.<font color='#BB00BB'>move_next</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
std::unique_ptr<font color='#5555FF'>&lt;</font>thread_function<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>ptr</font><font face='Lucida Console'>(</font><font color='#0000FF'>new</font> <font color='#BB00BB'>thread_function</font><font face='Lucida Console'>(</font><font color='#5555FF'>&amp;</font>impl2::read_thread,
_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>value</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>get</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,
_node_id,
_cons.<font color='#BB00BB'>element</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>key</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,
<font color='#BB00BB'>ref</font><font face='Lucida Console'>(</font>msg_buffer<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
threads.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>ptr<font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>bool</u></font> bsp_context::
<b><a name='receive_data'></a>receive_data</b> <font face='Lucida Console'>(</font>
std::shared_ptr<font color='#5555FF'>&lt;</font>std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>&gt;</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> item,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font><font color='#5555FF'>&amp;</font> sending_node_id
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#BB00BB'>notify_control_node</font><font face='Lucida Console'>(</font>impl2::IN_WAITING_STATE<font face='Lucida Console'>)</font>;
<font color='#0000FF'>while</font> <font face='Lucida Console'>(</font><font color='#979000'>true</font><font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// If there aren't any nodes left to give us messages then return right now.
</font> <font color='#009900'>// We need to check the msg_buffer size to make sure there aren't any
</font> <font color='#009900'>// unprocessed message there. Recall that this can happen because status
</font> <font color='#009900'>// messages always jump to the front of the message buffer. So we might have
</font> <font color='#009900'>// learned about the node terminations before processing their messages for us.
</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>num_terminated_nodes <font color='#5555FF'>=</font><font color='#5555FF'>=</font> _cons.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> msg_buffer.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>return</font> <font color='#979000'>false</font>;
<b>}</b>
<font color='#009900'>// if all running nodes are currently blocking forever on receive_data()
</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> outstanding_messages <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> num_terminated_nodes <font color='#5555FF'>+</font> num_waiting_nodes <font color='#5555FF'>=</font><font color='#5555FF'>=</font> _cons.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<b>{</b>
num_waiting_nodes <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
<font color='#BB00BB'>broadcast_byte</font><font face='Lucida Console'>(</font>impl2::SEE_ALL_IN_WAITING_STATE<font face='Lucida Console'>)</font>;
<font color='#009900'>// Note that the reason we have this epoch counter is so we can tell if a
</font> <font color='#009900'>// sent message is from before or after one of these "all nodes waiting"
</font> <font color='#009900'>// synchronization events. If we didn't have the epoch count we would have
</font> <font color='#009900'>// a race condition where one node gets the SEE_ALL_IN_WAITING_STATE
</font> <font color='#009900'>// message before others and then sends out a message to another node
</font> <font color='#009900'>// before that node got the SEE_ALL_IN_WAITING_STATE message. Then that
</font> <font color='#009900'>// node would think the normal message came before SEE_ALL_IN_WAITING_STATE
</font> <font color='#009900'>// which would be bad.
</font> <font color='#5555FF'>+</font><font color='#5555FF'>+</font>current_epoch;
<font color='#0000FF'>return</font> <font color='#979000'>false</font>;
<b>}</b>
impl1::msg_data data;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font>msg_buffer.<font color='#BB00BB'>pop</font><font face='Lucida Console'>(</font>data, current_epoch<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Error reading from msg_buffer in dlib::bsp_context.</font>"<font face='Lucida Console'>)</font>;
<font color='#0000FF'>switch</font><font face='Lucida Console'>(</font>data.msg_type<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>case</font> impl2::MESSAGE_HEADER: <b>{</b>
item <font color='#5555FF'>=</font> data.data;
sending_node_id <font color='#5555FF'>=</font> data.sender_id;
<font color='#BB00BB'>notify_control_node</font><font face='Lucida Console'>(</font>impl2::GOT_MESSAGE<font face='Lucida Console'>)</font>;
<font color='#0000FF'>return</font> <font color='#979000'>true</font>;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::IN_WAITING_STATE: <b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>num_waiting_nodes;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::GOT_MESSAGE: <b>{</b>
<font color='#5555FF'>-</font><font color='#5555FF'>-</font>outstanding_messages;
<font color='#5555FF'>-</font><font color='#5555FF'>-</font>num_waiting_nodes;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::SENT_MESSAGE: <b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>outstanding_messages;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::NODE_TERMINATE: <b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>num_terminated_nodes;
_cons[data.sender_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>terminated <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::SEE_ALL_IN_WAITING_STATE: <b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>current_epoch;
<font color='#0000FF'>return</font> <font color='#979000'>false</font>;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> impl2::READ_ERROR: <b>{</b>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>data.<font color='#BB00BB'>data_to_string</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>default</font>: <b>{</b>
<font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unknown message received by dlib::bsp_context</font>"<font face='Lucida Console'>)</font>;
<b>}</b> <font color='#0000FF'>break</font>;
<b>}</b> <font color='#009900'>// end switch()
</font> <b>}</b> <font color='#009900'>// end while (true)
</font> <b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>void</u></font> bsp_context::
<b><a name='notify_control_node'></a>notify_control_node</b> <font face='Lucida Console'>(</font>
<font color='#0000FF'><u>char</u></font> val
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>using</font> <font color='#0000FF'>namespace</font> impl2;
<font color='#0000FF'>switch</font><font face='Lucida Console'>(</font>val<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>case</font> SENT_MESSAGE: <b>{</b>
<font color='#5555FF'>+</font><font color='#5555FF'>+</font>outstanding_messages;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> GOT_MESSAGE: <b>{</b>
<font color='#5555FF'>-</font><font color='#5555FF'>-</font>outstanding_messages;
<b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>case</font> IN_WAITING_STATE: <b>{</b>
<font color='#009900'>// nothing to do in this case
</font> <b>}</b> <font color='#0000FF'>break</font>;
<font color='#0000FF'>default</font>:
<font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font><font color='#979000'>false</font>,"<font color='#CC0000'>This should never happen</font>"<font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#0000FF'>else</font>
<b>{</b>
<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>val, _cons[<font color='#979000'>0</font>]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
_cons[<font color='#979000'>0</font>]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>void</u></font> bsp_context::
<b><a name='broadcast_byte'></a>broadcast_byte</b> <font face='Lucida Console'>(</font>
<font color='#0000FF'><u>char</u></font> val
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> <font color='#BB00BB'>number_of_nodes</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#009900'>// don't send to yourself or to terminated nodes
</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>i <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#BB00BB'>node_id</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> _cons[i]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>terminated<font face='Lucida Console'>)</font>
<font color='#0000FF'>continue</font>;
<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>val, _cons[i]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
_cons[i]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<font color='#0000FF'><u>void</u></font> bsp_context::
<b><a name='send_data'></a>send_data</b><font face='Lucida Console'>(</font>
<font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>char</u></font><font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> item,
<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> target_node_id
<font face='Lucida Console'>)</font>
<b>{</b>
<font color='#0000FF'>using</font> <font color='#0000FF'>namespace</font> impl2;
<font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>_cons[target_node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>terminated<font face='Lucida Console'>)</font>
<font color='#0000FF'>throw</font> <font color='#BB00BB'>socket_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Attempt to send a message to a node that has terminated.</font>"<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>MESSAGE_HEADER, _cons[target_node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>current_epoch, _cons[target_node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
<font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item, _cons[target_node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream<font face='Lucida Console'>)</font>;
_cons[target_node_id]<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>stream.<font color='#BB00BB'>flush</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<font color='#BB00BB'>notify_control_node</font><font face='Lucida Console'>(</font>SENT_MESSAGE<font face='Lucida Console'>)</font>;
<b>}</b>
<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<b>}</b>
<font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_BSP_CPph_
</font>
</pre></body></html>