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
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
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
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
00258
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