Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

dataserver.h

Go to the documentation of this file.
00001 //**************************************************************************
00002 #ifndef _DATASERVER_H_
00003 #define _DATASERVER_H_
00004 //**************************************************************************
00005 #include "remotesocket.h"
00006 #include "keyinfo.h"
00007 #ifdef __GNUG__
00008 #include <vector.h>
00009 #include <map.h>
00010 #else
00011 #include <vector>
00012 #include <map>
00013 #endif
00014 #include <map>
00015 #include <string>
00016 #include <signal.h>
00017 //**************************************************************************
00018 #ifndef _THREAD_SAFE
00019 #define _THREAD_SAFE
00020 #endif
00021 //**************************************************************************
00022 typedef map <char *, int> Hash_Table;
00023 //typedef map <string, int> Hash_Table;
00024 //**************************************************************************
00025 class DataServer;
00026 class DataServerChildThread;
00027 class DataServerMainThread;
00028 typedef struct { 
00029         int ID; 
00030         int isRunning;
00031         DataServer *server; 
00032         DataServerChildThread *th;
00033         RemoteSocket *client;
00034         } ChildThreadStruct;
00035 //**************************************************************************
00036 class DataServer : protected RemoteSocket
00037 {
00038 private:
00039         friend class DataServerMainThread;
00040         friend class DataServerChildThread;
00041 
00042         int p_run_flag;
00043         int p_serverID;
00044         DataServerMainThread *Parent;
00045         vector<ChildThreadStruct *> child;
00046         Semaphore p_lock;
00047         Hash_Table p_hash_table;
00048         int start_time;
00049 
00050         int Terminate();
00051         int Finalize();
00052         int NumPendingThreads();
00053         int UpdateKeyTable();
00054         int Register() {int temp; return Register("", NULL, temp, true); }
00055         int Register(char *keyword, RemoteSocket *client, int &error_flag, bool register_flag = false);
00056         int RegisterExternal(char *keyword, RemoteSocket *client, int &error_flag, bool register_flag = false);
00057         int MapKey(char *key);
00058         Semaphore *Lock();
00059         Semaphore *Lock(char *key);
00060         // For executing the threads
00061         void RunThread(int clientID);
00062         int ClearLocks();
00063 
00065         virtual int RegisterInternal(char *keyword, RemoteSocket *client, int &error_flag, bool register_flag = false) { return 0; }
00066 
00067         template <class Etype>
00068         int Register_Variable_Internal(RemoteSocket *C, int &flag, char *inpkey, char *key, char *perm, Etype &data);
00069         template <class Etype>
00070         int Register_Structure_Internal(RemoteSocket *C, int &flag, char *inpkey, char *key, char *perm, Etype &data);
00071 
00072 protected:
00073         KeyTable *keytable;
00074         void (*callback)(char*);
00075         virtual bool isMaster()
00076                 { return true; }
00077         virtual void BroadcastData(void *var, int size) { }
00078         template <class Etype>
00079                 void BroadcastVariable(Etype *var, int n = 1)
00080                         { BroadcastData(var, sizeof(Etype)*n); }
00081         virtual void GetKeyword(RemoteSocket *C, char *key)
00082                 { C->RecvLine(key); }
00083         virtual int AcceptClient();
00084         virtual bool isRunningMPI()
00085                 { return false; }
00086         int Synchronize(char *filename = NULL);
00087         int RegisterKey(char *key, DataType desc, char *type, int elem_size, int num_elems, char *perm, void *ptr = NULL);
00088 
00090         template <class Etype>
00091         int Register_Variable(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype &data);
00092         template <class Etype>
00093         int Register_Structure(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype &data);
00094         template <class Etype>
00095         int Register_Static_Array(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, void *data, Etype &element, int totsize, int dim);
00096         template <class Etype>
00097         int Register_Dynamic_1D_Array(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype *data, int &n1);
00098         template <class Etype>
00099         int Register_Dynamic_2D_Array(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype **data, int &n1, int &n2);
00100         template <class Etype>
00101         int Register_Dynamic_3D_Array(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype ***data, int &n1, int &n2, int &n3);
00102         template <class Etype>
00103         int Register_Dynamic_4D_Array(RemoteSocket *C, int &flag, bool register_flag, char *inpkey, char *key, char *perm, Etype ****data, int &n1, int &n2, int &n3, int &n4);
00104 
00105 public:
00107         DataServer();
00108 
00110         DataServer(int port);
00111 
00113         int Start(int port = 4096);
00114 
00116         ~DataServer();
00117 
00119         void RegisterCallback(void (*cb)(char*));
00120 
00122         void RegisterCallback(char *key, void (*cb)(void*), void *data)
00123                 { keytable->RegisterCallback(key, cb, data); }
00124 
00126         int isRunning();
00127 
00129         int Stop();
00130 
00132         int Wait();
00133 
00135         int Post();
00136 
00138         int Wait(char *keyword);
00139 
00141         int Post(char *keyword);
00142 
00144         int SetDirty(char *keyword);
00145 
00147         int IsDirty(int change = 1);
00148 
00150         int IsDirty(char *keyword, int change = 1);
00151 
00153         int IsDirtyID(int id, int change = 1);
00154 
00156         void PrintDirty(ostream &out = cout, int change = 0);
00157 
00159         int NumKeys();
00160 
00162         char *Key(int i);
00163 
00165         char *GetValue(char *keyword);
00166 
00168         char *GetValue(int i);
00169 
00171         double BytesSent() { return TCPSocket::BytesSent(); }
00172 
00174         double BytesRecd() { return TCPSocket::BytesRecd(); }
00175 
00177         int SendTime() { return TCPSocket::SendTime(); }
00178 
00180         int RecvTime() { return TCPSocket::RecvTime(); }
00181 
00183         double SendRate() { return 8.0*BytesSent()/(1000.0*SendTime()); }
00184 
00186         double RecvRate() { return 8.0*BytesRecd()/(1000.0*RecvTime()); }
00187 
00188 };
00189 //**************************************************************************
00190 inline int DataServer::NumKeys()
00191 {
00192 return keytable->n;
00193 }
00194 //**************************************************************************
00195 inline char *DataServer::Key(int i)
00196 {
00197 return keytable->key[i].key;
00198 }
00199 //**************************************************************************
00200 inline int DataServer::isRunning()
00201 {
00202 return p_run_flag;
00203 }
00204 //**************************************************************************
00205 inline Semaphore *DataServer::Lock()
00206 {
00207 return &p_lock;
00208 }
00209 //**************************************************************************
00210 inline Semaphore *DataServer::Lock(char *key)
00211 {
00212 int id = MapKey(key);
00213 #ifdef ANIDEBUG
00214 cout << "DataServer::Lock: Looking for semaphore on key \"" << key << "\"." << endl << flush;
00215 #endif
00216 
00217 return keytable->key[id].sem;
00218 }
00219 //**************************************************************************
00220 inline int DataServer::Wait()
00221 {
00222 Lock()->Wait();
00223 return 0;
00224 }
00225 //**************************************************************************
00226 inline int DataServer::Post()
00227 {
00228 Lock()->Post();
00229 return 0;
00230 }
00231 //**************************************************************************
00232 inline int DataServer::Wait(char *key)
00233 {
00234 Lock(key)->Wait();
00235 return 0;
00236 }
00237 //**************************************************************************
00238 inline int DataServer::Post(char *key)
00239 {
00240 Lock(key)->Post();
00241 return 0;
00242 }
00243 //**************************************************************************
00244 inline int DataServer::MapKey(char *key)
00245 {
00246 static char prevkey[40] = "";
00247 static int prevID = -1;
00248 
00249 // Caching of last key
00250 if (strcmp(prevkey, key) == 0)
00251         return prevID;
00252 
00253 Hash_Table::const_iterator i = p_hash_table.find(key);
00254 
00255 if (i == p_hash_table.end())
00256         {
00257          // Double check due to STL hashing errors leading to
00258          // the key not being found inspite of being present.
00259          for (Hash_Table::const_iterator h = p_hash_table.begin(); h != p_hash_table.end(); h++)
00260                 if (strcmp(h->first, key) == 0)
00261                         {
00262                          cout << "STL hashing error encountered!!" << endl << flush;
00263                          return h->second;
00264                         }
00265          cout << "DataServer::MapKey: Error! Unidentified keyword \"" << key << "\"." << endl << flush;
00266          Finalize();
00267          exit(-1);
00268         }
00269 
00270 strcpy(prevkey, key);
00271 prevID = i->second;
00272 return i->second;
00273 }
00274 //**************************************************************************
00275 inline int DataServer::SetDirty(char *key)
00276 {
00277 int id = MapKey(key);
00278 #ifdef ANIDEBUG
00279 cout << "DataServer::SetDirty: Setting Dirty for key \"" << key << "\"." << endl << flush;
00280 #endif
00281 
00282 keytable->key[id].is_dirty = 1;
00283 
00284 return 0;
00285 }
00286 //**************************************************************************
00287 inline int DataServer::IsDirtyID(int id, int change)
00288 {
00289 int flag = keytable->key[id].is_dirty;
00290 if (change)
00291         keytable->key[id].is_dirty = 0;
00292 
00293 return flag;
00294 }
00295 //**************************************************************************
00296 inline int DataServer::IsDirty(char *key, int change)
00297 {
00298 int id = MapKey(key);
00299 int flag = keytable->key[id].is_dirty;
00300 if (change)
00301         keytable->key[id].is_dirty = 0;
00302 
00303 return flag;
00304 }
00305 //**************************************************************************
00306 inline int DataServer::IsDirty(int change)
00307 {
00308 int count = 0;
00309 for (int i = 0; i < keytable->n; i++)
00310         {
00311          count += keytable->key[i].is_dirty;
00312          if (change)
00313                 keytable->key[i].is_dirty = 0;
00314         }
00315 return count;
00316 }
00317 //**************************************************************************
00318 #include "dataserver_register_orig.h"
00319 #include "dataserver_register.h"
00320 //**************************************************************************
00321 #endif  // _DATASERVER_H_
00322 //**************************************************************************

Generated on Sun Jun 16 17:36:49 2002 for POSSE: Portable Object-oriented Scientific Steering Environment by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001