Index: prot_body.h =================================================================== --- prot_body.h (revision 290) +++ prot_body.h (working copy) @@ -74,6 +74,7 @@ ext int32 Last_discarded; ext int32 Last_delivered; ext int32 Last_seq; +ext int32 Token_rounds; ext token_header *Last_token; ext int Transitional; Index: spread_params.h =================================================================== --- spread_params.h (revision 290) +++ spread_params.h (working copy) @@ -68,6 +68,8 @@ #define MAX_SEQ_GAP 1600 /* used in flow control to limit difference between highest_seq and aru */ +#define MAX_EVS_ROUNDS 500 /* used in EVS state to limit total # of rounds to complete EVS */ + #define WATER_MARK 500 /* used to limit incoming user messages */ #define MAX_PRIVATE_NAME 10 /* not including the null, look for it if changed */ Index: membership.c =================================================================== --- membership.c (revision 290) +++ membership.c (working copy) @@ -2006,6 +2006,8 @@ { Net_send_token( &send_scat ); Net_send_token( &send_scat ); + Token_rounds = 0; + }else{ /* build first regular token */ send_scat.num_elements = 1; @@ -2017,6 +2019,7 @@ form_token->rtr_len = 0; Net_send_token( &send_scat ); + Token_rounds = 1; } Token_alive = 1; E_queue( Memb_token_loss, 0, NULL, Token_timeout ); Index: protocol.c =================================================================== --- protocol.c (revision 290) +++ protocol.c (working copy) @@ -615,6 +615,8 @@ } } + Token_rounds++; + if( Conf_leader( Memb_active_ptr() ) == My.id ) E_queue( Prot_token_hurry, 0, NULL, Hurry_timeout ); @@ -641,9 +643,34 @@ Deliver_agreed_packets(); Deliver_reliable_packets( Highest_seq-num_sent+1, num_sent ); + if( Memb_state() == EVS && Token_rounds > MAX_EVS_ROUNDS ) + { + Alarmp( SPLOG_WARNING, PRINT, "Prot_handle_token: BUG WORKAROUND: Too many rounds in EVS state; swallowing token; state:\n" ); + Alarmp( SPLOG_WARNING, PRINT, "\tAru: %d\n", Aru ); + Alarmp( SPLOG_WARNING, PRINT, "\tMy_aru: %d\n", My_aru ); + Alarmp( SPLOG_WARNING, PRINT, "\tHighest_seq: %d\n", Highest_seq ); + Alarmp( SPLOG_WARNING, PRINT, "\tHighest_fifo_seq: %d\n", Highest_fifo_seq ); + Alarmp( SPLOG_WARNING, PRINT, "\tLast_discarded: %d\n", Last_discarded ); + Alarmp( SPLOG_WARNING, PRINT, "\tLast_delivered: %d\n", Last_delivered ); + Alarmp( SPLOG_WARNING, PRINT, "\tLast_seq: %d\n", Last_seq ); + Alarmp( SPLOG_WARNING, PRINT, "\tToken_rounds: %d\n", Token_rounds ); + Alarmp( SPLOG_WARNING, PRINT, "Last Token:\n" ); + Alarmp( SPLOG_WARNING, PRINT, "\ttype: 0x%x\n", Last_token->type ); + Alarmp( SPLOG_WARNING, PRINT, "\ttransmiter_id: %d\n", Last_token->transmiter_id ); + Alarmp( SPLOG_WARNING, PRINT, "\tseq: %d\n", Last_token->seq ); + Alarmp( SPLOG_WARNING, PRINT, "\tproc_id: %d\n", Last_token->proc_id ); + Alarmp( SPLOG_WARNING, PRINT, "\taru: %d\n", Last_token->aru ); + Alarmp( SPLOG_WARNING, PRINT, "\taru_last_id: %d\n", Last_token->aru_last_id ); + Alarmp( SPLOG_WARNING, PRINT, "\tflow_control: %d\n", Last_token->flow_control ); + Alarmp( SPLOG_WARNING, PRINT, "\trtr_len: %d\n", Last_token->rtr_len ); + /*Alarmp( SPLOG_WARNING, PRINT, "\tconf_hash: %d\n", Last_token->conf_hash );*/ + + Memb_token_loss(); + } + GlobalStatus.highest_seq = Highest_seq; GlobalStatus.aru = Aru; - GlobalStatus.token_rounds++; + GlobalStatus.token_rounds = Token_rounds; } /* Basic algorithm: