00001
00002 #include "cms.hh"
00003 #include "timer.hh"
00004 #include "nmlqr.hh"
00005 #include "dbg_mem.h"
00006
00007 #ifdef EXTERN_C_STD_HEADERS
00008 extern "C"
00009 {
00010 #endif
00011
00012 #include <stdlib.h>
00013 #include <stddef.h>
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017
00018 #ifdef EXTERN_C_STD_HEADERS
00019 }
00020 #endif
00021
00022 #define ID_REQUEST_TYPE 9991
00023 #define ID_REPLY_TYPE 9992
00024 #define ID_DELETE_TYPE 9993
00025
00026 class ID_REQUEST:public NML_QUERY_MSG
00027 {
00028 public:
00029 ID_REQUEST ():NML_QUERY_MSG (ID_REQUEST_TYPE, sizeof (ID_REQUEST))
00030 {
00031 };
00032 void update (CMS *);
00033 };
00034
00035 void
00036 ID_REQUEST::update (CMS * cms)
00037 {
00038 }
00039
00040
00041 class ID_REPLY:public NML_QUERY_MSG
00042 {
00043 public:
00044 ID_REPLY ():NML_QUERY_MSG (ID_REPLY_TYPE, sizeof (ID_REPLY))
00045 {
00046 };
00047 void update (CMS *);
00048 int subdiv;
00049 };
00050
00051 void
00052 ID_REPLY::update (CMS * cms)
00053 {
00054 cms->update (subdiv);
00055 }
00056
00057
00058 class ID_DELETE:public NML_QUERY_MSG
00059 {
00060 public:
00061 ID_DELETE ():NML_QUERY_MSG (ID_DELETE_TYPE, sizeof (ID_DELETE))
00062 {
00063 };
00064 void update (CMS *);
00065 int subdiv;
00066 };
00067
00068 void
00069 ID_DELETE::update (CMS * cms)
00070 {
00071 cms->update (subdiv);
00072 }
00073
00074 void
00075 NML_QUERY_MSG::update (CMS * cms)
00076 {
00077 cms->update (subdiv_for_reply);
00078 }
00079
00080 int
00081 queryFormat (NMLTYPE type, void *buf, CMS * cms)
00082 {
00083 ((NML_QUERY_MSG *) buf)->update (cms);
00084 return 0;
00085 }
00086
00087
00088 int
00089 idFormat (NMLTYPE type, void *buf, CMS * cms)
00090 {
00091 queryFormat (type, buf, cms);
00092 switch (type)
00093 {
00094 case ID_REQUEST_TYPE:
00095 ((ID_REQUEST *) buf)->update (cms);
00096 break;
00097
00098 case ID_REPLY_TYPE:
00099 ((ID_REPLY *) buf)->update (cms);
00100 break;
00101
00102 case ID_DELETE_TYPE:
00103 ((ID_DELETE *) buf)->update (cms);
00104 break;
00105
00106 default:
00107 return 0;
00108 }
00109 return 1;
00110 }
00111
00112
00113 NML_QR_SERVER::NML_QR_SERVER (NML_FORMAT_PTR f_ptr,
00114 char *qr_name, char *process_name,
00115 char *config_file)
00116 {
00117
00118 queryChannel = NULL;
00119 replyChannel = NULL;
00120 idChannel = NULL;
00121 reply_subdiv = -1;
00122 subdiv_allocation_table = NULL;
00123
00124 char repbufname[40];
00125 sprintf (repbufname, "%sReply", qr_name);
00126 char querybufname[40];
00127 sprintf (querybufname, "%sQuery", qr_name);
00128 char idbufname[40];
00129 sprintf (idbufname, "%sID", qr_name);
00130 idChannel =
00131 new NML_ID_CHANNEL (f_ptr, idbufname, process_name, config_file);
00132 queryChannel =
00133 new NML_QUERY_CHANNEL (f_ptr, querybufname, process_name, config_file);
00134 replyChannel = new NML (f_ptr, repbufname, process_name, config_file);
00135
00136 if (replyChannel->get_total_subdivisions () > 1)
00137 {
00138 subdiv_allocation_table =
00139 (char *) DEBUG_MALLOC (replyChannel->get_total_subdivisions ());
00140 }
00141 memset (subdiv_allocation_table, 0,
00142 replyChannel->get_total_subdivisions ());
00143 }
00144
00145
00146 NML_QR_SERVER::~NML_QR_SERVER ()
00147 {
00148 if (NULL != queryChannel)
00149 {
00150 delete queryChannel;
00151 queryChannel = NULL;
00152 }
00153 if (NULL != idChannel)
00154 {
00155 delete idChannel;
00156 idChannel = NULL;
00157 }
00158 if (NULL != replyChannel)
00159 {
00160 delete replyChannel;
00161 replyChannel = NULL;
00162 }
00163 if (NULL != subdiv_allocation_table)
00164 {
00165 DEBUG_FREE (subdiv_allocation_table);
00166 subdiv_allocation_table = NULL;
00167 }
00168 }
00169
00170 NMLTYPE
00171 NML_QR_SERVER::readQuery ()
00172 {
00173 while (1)
00174 {
00175 NMLTYPE query_read_type;
00176 switch (query_read_type = queryChannel->read ())
00177 {
00178 case ID_REQUEST_TYPE:
00179 {
00180 int subdiv_found = 0;
00181 for (int i = 0; i < replyChannel->get_total_subdivisions (); i++)
00182 {
00183 if (subdiv_allocation_table[i] == 0)
00184 {
00185 subdiv_allocation_table[i] = 1;
00186 ID_REPLY idMsg;
00187 idMsg.subdiv = i;
00188 idChannel->write (idMsg);
00189 subdiv_found = 1;
00190 break;
00191 }
00192 }
00193 if (!subdiv_found)
00194 {
00195
00196 ID_REPLY idMsg;
00197 idMsg.subdiv = -1;
00198 idChannel->write (idMsg);
00199 }
00200 }
00201 break;
00202
00203 case ID_REPLY_TYPE:
00204 return -1;
00205 break;
00206
00207 case ID_DELETE_TYPE:
00208 {
00209 ID_DELETE *idDeleteMsg =
00210 (ID_DELETE *) queryChannel->get_address ();
00211 if (idDeleteMsg->subdiv >= 0
00212 && idDeleteMsg->subdiv <
00213 replyChannel->get_total_subdivisions ())
00214 {
00215 subdiv_allocation_table[idDeleteMsg->subdiv] = 0;
00216 }
00217 }
00218 break;
00219
00220 default:
00221 NML_QUERY_MSG * qMsg =
00222 (NML_QUERY_MSG *) queryChannel->get_address ();
00223 reply_subdiv = qMsg->subdiv_for_reply;
00224 return query_read_type;
00225 }
00226 }
00227 }
00228
00229 NMLTYPE
00230 NML_QR_SERVER::waitForQuery (double timeout)
00231 {
00232 while (1)
00233 {
00234 NMLTYPE query_read_type;
00235 switch (query_read_type = queryChannel->blocking_read (timeout))
00236 {
00237 case ID_REQUEST_TYPE:
00238 {
00239 int subdiv_found = 0;
00240 for (int i = 0; i < replyChannel->get_total_subdivisions (); i++)
00241 {
00242 if (subdiv_allocation_table[i] == 0)
00243 {
00244 subdiv_allocation_table[i] = 1;
00245 ID_REPLY idMsg;
00246 idMsg.subdiv = i;
00247 idChannel->write (idMsg);
00248 subdiv_found = 1;
00249 break;
00250 }
00251 }
00252 if (!subdiv_found)
00253 {
00254
00255 ID_REPLY idMsg;
00256 idMsg.subdiv = -1;
00257 idChannel->write (idMsg);
00258 }
00259 }
00260 break;
00261
00262 case ID_REPLY_TYPE:
00263 return -1;
00264 break;
00265
00266 case ID_DELETE_TYPE:
00267 {
00268 ID_DELETE *idDeleteMsg =
00269 (ID_DELETE *) queryChannel->get_address ();
00270 if (idDeleteMsg->subdiv >= 0
00271 && idDeleteMsg->subdiv <
00272 replyChannel->get_total_subdivisions ())
00273 {
00274 subdiv_allocation_table[idDeleteMsg->subdiv] = 0;
00275 }
00276 }
00277 break;
00278
00279 default:
00280 NML_QUERY_MSG * qMsg =
00281 (NML_QUERY_MSG *) queryChannel->get_address ();
00282 reply_subdiv = qMsg->subdiv_for_reply;
00283 return query_read_type;
00284 }
00285 }
00286 }
00287
00288 NMLmsg *
00289 NML_QR_SERVER::getQueryAddress ()
00290 {
00291 if (NULL == queryChannel)
00292 {
00293 return NULL;
00294 }
00295 return queryChannel->get_address ();
00296 }
00297
00298
00299 int
00300 NML_QR_SERVER::replyToLastQuery (NMLmsg * message_to_send)
00301 {
00302 if (NULL == replyChannel)
00303 {
00304 return -1;
00305 }
00306 if (reply_subdiv < 0
00307 || reply_subdiv > replyChannel->get_total_subdivisions ())
00308 {
00309 return -1;
00310 }
00311 return replyChannel->write_subdivision (reply_subdiv, message_to_send);
00312 }
00313
00314
00315 int
00316 NML_QR_SERVER::valid ()
00317 {
00318 if (!idChannel->valid ())
00319 {
00320 return 0;
00321 }
00322 if (!queryChannel->valid ())
00323 {
00324 return 0;
00325 }
00326 if (!replyChannel->valid ())
00327 {
00328 return 0;
00329 }
00330 return 1;
00331 }
00332
00333 int
00334 NML_QR_SERVER::reset ()
00335 {
00336 if (!idChannel->valid ())
00337 {
00338 idChannel->reset ();
00339 }
00340 if (!queryChannel->valid ())
00341 {
00342 queryChannel->reset ();
00343 }
00344 if (!replyChannel->valid ())
00345 {
00346 replyChannel->reset ();
00347 }
00348 return valid ();
00349 }
00350
00351
00352
00353 NML_QR_CLIENT::NML_QR_CLIENT (NML_FORMAT_PTR f_ptr, char *qr_name,
00354 char *process_name, char *config_file)
00355 {
00356 queryChannel = NULL;
00357 replyChannel = NULL;
00358 idChannel = NULL;
00359 reply_subdiv = -1;
00360
00361 char repbufname[40];
00362 sprintf (repbufname, "%sReply", qr_name);
00363 char querybufname[40];
00364 sprintf (querybufname, "%sQuery", qr_name);
00365 char idbufname[40];
00366 sprintf (idbufname, "%sID", qr_name);
00367 idChannel =
00368 new NML_ID_CHANNEL (f_ptr, idbufname, process_name, config_file);
00369 queryChannel =
00370 new NML_QUERY_CHANNEL (f_ptr, querybufname, process_name, config_file);
00371 replyChannel = new NML (f_ptr, repbufname, process_name, config_file);
00372
00373 if (idChannel->valid () && queryChannel->valid ())
00374 {
00375 ID_REQUEST reqMsg;
00376 queryChannel->write (reqMsg);
00377 esleep (0.05);
00378 while (!idChannel->read ())
00379 {
00380 esleep (0.05);
00381 }
00382 ID_REPLY *idReply = (ID_REPLY *) idChannel->get_address ();
00383 if (idReply->type == ID_REPLY_TYPE)
00384 {
00385 reply_subdiv = idReply->subdiv;
00386 }
00387 }
00388 }
00389
00390 NML_QR_CLIENT::~NML_QR_CLIENT ()
00391 {
00392 if (NULL != queryChannel)
00393 {
00394 if (reply_subdiv >= 0)
00395 {
00396 ID_DELETE idDeleteMsg;
00397 idDeleteMsg.subdiv_for_reply = reply_subdiv;
00398 idDeleteMsg.subdiv = reply_subdiv;
00399 queryChannel->write (&idDeleteMsg);
00400 esleep (0.05);
00401 }
00402 delete queryChannel;
00403 queryChannel = NULL;
00404 }
00405 if (NULL != idChannel)
00406 {
00407 delete idChannel;
00408 idChannel = NULL;
00409 }
00410 if (NULL != replyChannel)
00411 {
00412 delete replyChannel;
00413 replyChannel = NULL;
00414 }
00415 }
00416
00417 int
00418 NML_QR_CLIENT::sendQuery (NML_QUERY_MSG * qMsg)
00419 {
00420 if (NULL == queryChannel)
00421 {
00422 return -1;
00423 }
00424 qMsg->subdiv_for_reply = reply_subdiv;
00425 return queryChannel->write (qMsg);
00426 }
00427
00428
00429 NMLTYPE
00430 NML_QR_CLIENT::readReply ()
00431 {
00432 if (NULL == replyChannel || reply_subdiv < 0)
00433 {
00434 return -1;
00435 }
00436 return replyChannel->read_subdivision (reply_subdiv);
00437 }
00438
00439
00440 NMLTYPE
00441 NML_QR_CLIENT::waitForReply (double timeout)
00442 {
00443 if (NULL == replyChannel || reply_subdiv < 0)
00444 {
00445 return -1;
00446 }
00447 return replyChannel->blocking_read_subdivision (reply_subdiv, timeout);
00448 }
00449
00450 NMLmsg *
00451 NML_QR_CLIENT::getReplyAddress ()
00452 {
00453 if (NULL == replyChannel || reply_subdiv < 0)
00454 {
00455 return NULL;
00456 }
00457 return replyChannel->get_address_subdivision (reply_subdiv);
00458 }
00459
00460
00461 int
00462 NML_QR_CLIENT::valid ()
00463 {
00464 if (!idChannel->valid ())
00465 {
00466 return 0;
00467 }
00468 if (!queryChannel->valid ())
00469 {
00470 return 0;
00471 }
00472 if (!replyChannel->valid ())
00473 {
00474 return 0;
00475 }
00476 if (reply_subdiv < 0)
00477 {
00478 return 0;
00479 }
00480 return 1;
00481 }
00482
00483 int
00484 NML_QR_CLIENT::reset ()
00485 {
00486 if (!idChannel->valid ())
00487 {
00488 idChannel->reset ();
00489 }
00490 if (!queryChannel->valid ())
00491 {
00492 queryChannel->reset ();
00493 }
00494 if (!replyChannel->valid ())
00495 {
00496 replyChannel->reset ();
00497 }
00498 if (idChannel->valid () && queryChannel->valid () && reply_subdiv < 0)
00499 {
00500 ID_REQUEST reqMsg;
00501 queryChannel->write (reqMsg);
00502 esleep (0.05);
00503 while (!idChannel->read ())
00504 {
00505 esleep (0.05);
00506 }
00507 ID_REPLY *idReply = (ID_REPLY *) idChannel->get_address ();
00508 if (idReply->type == ID_REPLY_TYPE)
00509 {
00510 reply_subdiv = idReply->subdiv;
00511 }
00512 }
00513 return valid ();
00514 }
00515
00516
00517 NML_QUERY_CHANNEL::NML_QUERY_CHANNEL (NML_FORMAT_PTR f_ptr, char *name,
00518 char *process, char *file,
00519 int set_to_server):
00520 NML (name, process, file, set_to_server)
00521 {
00522 format_chain = new RCS_LINKED_LIST;
00523 prefix_format_chain (f_ptr);
00524 prefix_format_chain (idFormat);
00525 channel_type = NML_QUERY_CHANNEL_TYPE;
00526 sizeof_message_header = sizeof (NML_QUERY_MSG);
00527
00528 if (NULL != cms)
00529 {
00530 cms->sizeof_message_header = sizeof_message_header;
00531 }
00532
00533 register_with_server ();
00534
00535 }
00536
00537 NML_QUERY_CHANNEL::~NML_QUERY_CHANNEL ()
00538 {
00539
00540 }
00541
00542
00543 NML_ID_CHANNEL::NML_ID_CHANNEL (NML_FORMAT_PTR f_ptr, char *name,
00544 char *process, char *file, int set_to_server):
00545 NML (name, process, file, set_to_server)
00546 {
00547 format_chain = new RCS_LINKED_LIST;
00548 prefix_format_chain (idFormat);
00549 channel_type = NML_ID_CHANNEL_TYPE;
00550 sizeof_message_header = sizeof (NML_QUERY_MSG);
00551
00552 if (NULL != cms)
00553 {
00554 cms->sizeof_message_header = sizeof_message_header;
00555 }
00556
00557 register_with_server ();
00558
00559 }
00560
00561 NML_ID_CHANNEL::~NML_ID_CHANNEL ()
00562 {
00563
00564 }