statmch.c
上传用户:allwinjm
上传日期:2021-08-29
资源大小:99k
文件大小:3k
源码类别:

Internet/IE编程

开发平台:

Unix_Linux

  1. /************************************************************************ 
  2.  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) 
  3.  * Copyright (C) 2001-2003 Optical Access 
  4.  * Author: Alex Rozin 
  5.  * 
  6.  * This file is part of RSTP library. 
  7.  * 
  8.  * RSTP library is free software; you can redistribute it and/or modify it 
  9.  * under the terms of the GNU Lesser General Public License as published by the 
  10.  * Free Software Foundation; version 2.1 
  11.  * 
  12.  * RSTP library is distributed in the hope that it will be useful, but 
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser 
  15.  * General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public License 
  18.  * along with RSTP library; see the file COPYING.  If not, write to the Free 
  19.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
  20.  * 02111-1307, USA. 
  21.  **********************************************************************/
  22. /* Generic (abstract) state machine : 17.13, 17.14 */
  23.  
  24. #include "base.h"
  25. #include "statmch.h"
  26. #if STP_DBG
  27. #  include "stpm.h"
  28. #endif
  29. STATE_MACH_T *
  30. STP_state_mach_create (void (*concreteEnterState) (STATE_MACH_T*),
  31.                        Bool (*concreteCheckCondition) (STATE_MACH_T*),
  32.                        char *(*concreteGetStatName) (int),
  33.                        void *owner, char *name)
  34. {
  35.   STATE_MACH_T *this;
  36.   STP_MALLOC(this, STATE_MACH_T, "state machine");
  37.  
  38.   this->State = BEGIN;
  39.   this->name = (char*) strdup (name);
  40.   this->changeState = False;
  41. #if STP_DBG
  42.   this->debug = False;
  43.   this->ignoreHop2State = BEGIN;
  44. #endif
  45.   this->concreteEnterState = concreteEnterState;
  46.   this->concreteCheckCondition = concreteCheckCondition;
  47.   this->concreteGetStatName = concreteGetStatName;
  48.   this->owner.owner = owner;
  49.   return this;
  50. }
  51.                               
  52. void
  53. STP_state_mach_delete (STATE_MACH_T *this)
  54. {
  55.   free (this->name);
  56.   STP_FREE(this, "state machine");
  57. }
  58. Bool
  59. STP_check_condition (STATE_MACH_T* this)
  60. {
  61.   Bool bret;
  62.   bret = (*(this->concreteCheckCondition)) (this);
  63.   if (bret) {
  64.     this->changeState = True;
  65.   }
  66.   
  67.   return bret;
  68. }
  69.         
  70. Bool
  71. STP_change_state (STATE_MACH_T* this)
  72. {
  73.   register int number_of_loops;
  74.   for (number_of_loops = 0; ; number_of_loops++) {
  75.     if (! this->changeState) return number_of_loops;
  76.     (*(this->concreteEnterState)) (this);
  77.     this->changeState = False;
  78.     STP_check_condition (this);
  79.   }
  80.   return number_of_loops;
  81. }
  82. Bool
  83. STP_hop_2_state (STATE_MACH_T* this, unsigned int new_state)
  84. {
  85. #ifdef STP_DBG
  86.   switch (this->debug) {
  87.     case 0: break;
  88.     case 1:
  89.       if (new_state == this->State || new_state == this->ignoreHop2State) break;
  90.       stp_trace ("%-8s(%s-%s): %s=>%s",
  91.         this->name,
  92.         *this->owner.port->owner->name ? this->owner.port->owner->name : "Glbl",
  93.         this->owner.port->port_name,
  94.         (*(this->concreteGetStatName)) (this->State),
  95.         (*(this->concreteGetStatName)) (new_state));
  96.       break;
  97.     case 2:
  98.       if (new_state == this->State) break;
  99.       stp_trace ("%s(%s): %s=>%s", 
  100.         this->name,
  101.         *this->owner.stpm->name ? this->owner.stpm->name : "Glbl",
  102.         (*(this->concreteGetStatName)) (this->State),
  103.         (*(this->concreteGetStatName)) (new_state));
  104.       break;
  105.   }
  106. #endif
  107.   this->State = new_state;
  108.   this->changeState = True;
  109.   return True;
  110. }