00001 /* 00002 ** RingReaderServer -- a class of server that reads messages from a Ring 00003 ** as input. 00004 ** This class remains virtual because it does not 00005 ** implement method ClientServicer() 00006 */ 00007 //--------------------------------------------------------------------------- 00008 #ifndef ringreaderserverH 00009 #define ringreaderserverH 00010 //--------------------------------------------------------------------------- 00011 #include "serverbase.h" 00012 00013 extern "C" { 00014 #include <transport.h> 00015 } 00016 00017 00018 00019 00020 #define SERVE_MAX_LOGOS 20 // maximum incoming logo ids 00021 00022 00023 // sacred definitions for message types to report to heartbeat/status ring 00024 // 00025 #define ERR_MISSMSG 0 /* message missed in transport ring */ 00026 #define ERR_TOOBIG 1 /* retreived msg too large for buffer */ 00027 #define ERR_NOTRACK 2 /* severe weirdness in the cellar */ 00028 #define ERR_QUEUE 3 /* error queueing message for sending */ 00029 00030 //--------------------------------------------------------------------------- 00031 class RingReaderServer : public WormServerBase 00032 { 00033 private: 00034 int MaxMessageLength; 00035 char * MessageBuffer; // buffer for arriving messages 00036 00037 protected: 00038 00039 // ======================================================================= 00040 // from TConfigurable 00041 // ======================================================================= 00042 00043 /* CheckConfig() -- allows derivative classes to report the status of their 00044 ** the lookup values. 00045 ** 00046 ** From within any deriving class, or further derivation, ALWAYS contain a call to 00047 ** <super_class>::CheckConfig() in their own CheckConfig() method... 00048 ** this ensures that all classes in the heirarchy get their chance to report status. 00049 ** 00050 ** All implementations should set ConfigStatus value to WORM_STAT_BADSTATE if there 00051 ** is a configuration problem, otherwise leave it alone. 00052 */ 00053 virtual void CheckConfig(); 00054 00055 // ======================================================================= 00056 // WormServerBase 00057 // ======================================================================= 00058 00059 /* PrepareToRun() -- actions to take prior to entering main loop 00060 ** 00061 ** ALWAYS call base class's PrepareToRun() at the top 00062 ** 00063 ** RETURN: true if ready 00064 ** false if some condition prevents proper execution 00065 */ 00066 bool PrepareToRun(); 00067 00068 /* MainThreadActions() -- override to implements actions performed during the main 00069 ** thread's loop (other than sending heartbeats, which are 00070 ** handled by other code. 00071 ** This is made virtual since some servers may look for input 00072 ** from a ring, some may look into the database, while others 00073 ** may only respond to requests from clients. 00074 ** 00075 ** For DisplayServer class, purge old quakes when they expire from the history 00076 */ 00077 WORM_STATUS_CODE MainThreadActions(); 00078 00079 /* FinishedRunning() -- actions to take after exiting main loop 00080 ** 00081 ** ALWAYS call base class's FinishedRunning() 00082 ** 00083 ** For DisplayServer class, just use base class's 00084 */ 00085 void FinishedRunning(); 00086 00087 00088 /* ClientServicer() -- method to perform the work of servicing a client 00089 ** 00090 ** note: THREAD_RETURN is some kind of void, so just return or leave block 00091 */ 00092 // virtual THREAD_RETURN ClientServicer( void * p_socketdescriptor ); 00093 00094 00095 // ======================================================================= 00096 // RingReaderServer 00097 // ======================================================================= 00098 00099 int LoggingLevel; 00100 00101 // Ring to check for shutdown messages, to post heartbeats, etc. 00102 WORM_RING_NAME InputRingName; // name of transport ring for message input 00103 WORM_RING_ID InputRingKey; // key to transport ring to read messages from 00104 SHM_INFO InputRegion; // Info structure for shared memory (input ring) 00105 00106 MSG_LOGO ServeLogo[SERVE_MAX_LOGOS]; 00107 short ServeLogoCount; 00108 00109 // MessageMutex -- mutex to prevent collisions over the MessageBuffer, 00110 // should be used in both MessageFromRing() 00111 // and ClientServicer() 00112 // 00113 // MessageMutex.RequestLock(); 00114 // MessageMutex.ReleaseLock(); 00115 // 00116 TMutex * MessageMutex; 00117 00118 /* 00119 ** MessageFromRing() -- method for derivative classes to use to 00120 ** perform the actual handling of message 00121 ** as they arrive on the ring. 00122 */ 00123 virtual bool MessageFromRing( const MSG_LOGO p_msglogo, const char * p_msg ) = 0; 00124 00125 public: 00126 00127 // ======================================================================= 00128 // from TConfigurable 00129 // ======================================================================= 00130 00131 /* 00132 ** HandleConfigLine() 00133 ** 00134 ** PARMS: 00135 ** p_parser -- the parser being used, command string already 00136 ** in the current token for comparison with Its() 00137 ** 00138 ** RETURN: 00139 ** HANDLE_INVALID -- line invalid 00140 ** HANDLE_UNUSED -- line not used 00141 ** HANDLE_USED -- line used okay 00142 ** 00143 ** Override for child classes to handle command lines 00144 */ 00145 HANDLE_STATUS HandleConfigLine( ConfigSource * p_parser ); 00146 00147 // ======================================================================= 00148 // RingReaderServer 00149 // ======================================================================= 00150 00151 RingReaderServer(); 00152 ~RingReaderServer(); 00153 00154 }; 00155 00156 #endif 00157