Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

ArClientHandlerConfig.cpp

Go to the documentation of this file.
00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArClientHandlerConfig.h"
00029 #include "ArClientArgUtils.h"
00030 
00031 #define ARDEBUG_CLIENTHANDLERCONFIG
00032 
00033 #if (defined(_DEBUG) && defined(ARDEBUG_CLIENTHANDLERCONFIG))
00034 #define IFDEBUG(code) {code;}
00035 #else
00036 #define IFDEBUG(code)
00037 #endif 
00038 
00043 AREXPORT ArClientHandlerConfig::ArClientHandlerConfig(ArClientBase *client,
00044                                                                                           bool ignoreBounds,
00045                                                       const char *robotName) :
00046   myRobotName((robotName != NULL) ? robotName : ""),
00047   myLogPrefix(),
00048 
00049   myConfig(NULL, false, ignoreBounds),
00050   myDefaultConfig(NULL),
00051 
00052   myHandleGetConfigBySectionsCB(this, &ArClientHandlerConfig::handleGetConfigBySections),
00053   myHandleGetConfigCB(this, &ArClientHandlerConfig::handleGetConfig),
00054   myHandleSetConfigCB(this, &ArClientHandlerConfig::handleSetConfig),
00055   myHandleGetConfigDefaultsCB(this, 
00056                               &ArClientHandlerConfig::handleGetConfigDefaults),
00057   myHandleGetConfigSectionFlagsCB(this, 
00058                                   &ArClientHandlerConfig::handleGetConfigSectionFlags)
00059 {
00060   myClient = client;
00061   myHaveGottenConfig = false;
00062   myHaveRequestedDefaults = false;
00063   myHaveGottenDefaults = false;
00064   myHaveRequestedDefaultCopy = false;
00065 
00066   if (!myRobotName.empty()) {
00067     myLogPrefix = myRobotName + ": ";
00068   }
00069 
00070   myConfig.setConfigName("Server", myRobotName.c_str());
00071 
00072 }
00073 
00074 AREXPORT ArClientHandlerConfig::~ArClientHandlerConfig()
00075 {
00076 
00077 }
00078 
00083 AREXPORT void ArClientHandlerConfig::requestConfigFromServer(void)
00084 {
00085   myDataMutex.lock();
00086 
00087   char *getConfigPacketName = "getConfigBySections";
00088   ArFunctor1C<ArClientHandlerConfig, ArNetPacket *> *getConfigCB = &myHandleGetConfigBySectionsCB;
00089 
00090   if (!myClient->dataExists(getConfigPacketName)) {
00091     getConfigPacketName = "getConfig";
00092     getConfigCB = &myHandleGetConfigCB;
00093   }
00094 
00095   myConfig.clearSections();
00096 
00097   myClient->remHandler(getConfigPacketName, getConfigCB);
00098   myClient->addHandler(getConfigPacketName, getConfigCB);
00099   myClient->remHandler("setConfig", &myHandleSetConfigCB);
00100   myClient->addHandler("setConfig", &myHandleSetConfigCB);
00101 
00102   if (myClient->dataExists("getConfigDefaults")) {
00103     myClient->remHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB);
00104     myClient->addHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB);
00105   }
00106   if (myClient->dataExists("getConfigSectionFlags"))
00107   {
00108     myClient->remHandler("getConfigSectionFlags", 
00109                          &myHandleGetConfigSectionFlagsCB);
00110     myClient->addHandler("getConfigSectionFlags", 
00111                          &myHandleGetConfigSectionFlagsCB);
00112     myClient->requestOnce("getConfigSectionFlags");
00113   }
00114   myClient->requestOnce(getConfigPacketName);
00115   myHaveGottenConfig = false;
00116 
00117   
00118   myDataMutex.unlock();
00119 }
00120 
00121 AREXPORT void ArClientHandlerConfig::handleGetConfigBySections(ArNetPacket *packet)
00122 {
00123   handleGetConfigData(packet, true);
00124 }
00125 
00126 AREXPORT void ArClientHandlerConfig::handleGetConfig(ArNetPacket *packet)
00127 {
00128   handleGetConfigData(packet, false);
00129 }
00130 
00131 AREXPORT void ArClientHandlerConfig::handleGetConfigData(ArNetPacket *packet,
00132                                                          bool isMultiplePackets)
00133 {
00134   char name[32000];
00135   char comment[32000];
00136   char type;
00137   std::string section;
00138   
00139   // The multiple packets method also sends display hints with the parameters;
00140   // the old single packet method does not.
00141   ArClientArg clientArg(isMultiplePackets);
00142   bool isEmptyPacket = true;
00143 
00144   myDataMutex.lock();
00145 
00146   while (packet->getDataReadLength() < packet->getDataLength())
00147   {
00148     isEmptyPacket = false;
00149 
00150     type = packet->bufToByte();
00151 
00152     if (type == 'S')
00153     {
00154       packet->bufToStr(name, sizeof(name));
00155       packet->bufToStr(comment, sizeof(name));
00156       //printf("%c %s %s\n", type, name, comment);
00157 
00158       ArLog::log(ArLog::Verbose, "%sReceiving config section %s...", 
00159                  myLogPrefix.c_str(), name);
00160       
00161       section = name;
00162       myConfig.setSectionComment(name, comment);
00163     }
00164     else if (type == 'P')
00165     {
00166                   ArConfigArg configArg;
00167 
00168                   bool isSuccess = clientArg.createArg(packet,
00169                                                                                                              configArg);
00170                   if (isSuccess) {
00171 
00172                           myConfig.addParam(configArg,
00173                                                                     section.c_str(),
00174                                                                     configArg.getConfigPriority(),
00175                           configArg.getDisplayHint());
00176                   }
00177                   else
00178                   {
00179                           ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown param type");
00180                   }
00181     }
00182     else // unrecognized header
00183     {
00184       ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown type");
00185     }
00186   
00187   } // end while more to read
00188 
00189   if (!isMultiplePackets || isEmptyPacket) {
00190 
00191     ArLog::log(ArLog::Normal, "%sGot config from server.", myLogPrefix.c_str());
00192     IFDEBUG(myConfig.log());
00193 
00194     myHaveGottenConfig = true;
00195   }
00196 
00197   myDataMutex.unlock();
00198 
00199 
00200 
00201   if (myHaveGottenConfig) {
00202 
00203     myCallbackMutex.lock();
00204 
00205     for (std::list<ArFunctor *>::iterator it = myGotConfigCBList.begin(); 
00206         it != myGotConfigCBList.end(); 
00207         it++) {
00208       (*it)->invoke();
00209     }
00210     myCallbackMutex.unlock();
00211 
00212   } // end if config received
00213 
00214 } // end method handleGetConfigData
00215 
00216 AREXPORT void ArClientHandlerConfig::handleGetConfigSectionFlags(
00217         ArNetPacket *packet) 
00218 {
00219   int numSections = packet->bufToByte4();
00220   
00221   int i;
00222 
00223   char section[32000];
00224   char flags[32000];
00225 
00226   myDataMutex.lock();
00227   for (i = 0; i < numSections; i++)
00228   {
00229     packet->bufToStr(section, sizeof(section));
00230     packet->bufToStr(flags, sizeof(flags));
00231     myConfig.addSectionFlags(section, flags);
00232   }
00233   myDataMutex.unlock();
00234 }
00235 
00236 AREXPORT void ArClientHandlerConfig::saveConfigToServer(void)
00237 {
00238   saveConfigToServer(&myConfig);
00239 }
00240 
00241 AREXPORT void ArClientHandlerConfig::saveConfigToServer(
00242           ArConfig *config, 
00243           const std::set<std::string, ArStrCaseCmpOp> *ignoreTheseSections)
00244 {
00245   //ArConfigArg param;
00246   ArClientArg clientArg;
00247 
00248   ArNetPacket sending;
00249   ArLog::log(ArLog::Normal, "%sSaving config to server", myLogPrefix.c_str());
00250 
00251   myDataMutex.lock();
00252   std::list<ArConfigSection *> *sections = config->getSections();
00253   for (std::list<ArConfigSection *>::iterator sIt = sections->begin(); 
00254        sIt != sections->end(); 
00255        sIt++)
00256   {
00257     ArConfigSection *section = (*sIt);
00258     // if we're ignoring sections and we're ignoring this one, then
00259     // don't send it
00260     if (ignoreTheseSections != NULL && 
00261         (ignoreTheseSections->find(section->getName()) != 
00262          ignoreTheseSections->end()))
00263     {
00264       ArLog::log(ArLog::Verbose, "Not sending section %s", 
00265                  section->getName());
00266       continue;
00267     }
00268     sending.strToBuf("Section");
00269     sending.strToBuf(section->getName());
00270     std::list<ArConfigArg> *params = section->getParams();
00271 
00272     for (std::list<ArConfigArg>::iterator pIt = params->begin(); 
00273          pIt != params->end(); 
00274          pIt++)
00275     {
00276       ArConfigArg &param = (*pIt);
00277 
00278       if (!clientArg.isSendableParamType(param)) {
00279         continue;
00280       }
00281 
00282       sending.strToBuf(param.getName());
00283 
00284       clientArg.argTextToBuf(param, &sending);
00285 
00286     } // end for each param
00287   } // end for each section
00288 
00289   myDataMutex.unlock();
00290   myClient->requestOnce("setConfig", &sending);
00291 }
00292 
00293 AREXPORT void ArClientHandlerConfig::handleSetConfig(ArNetPacket *packet)
00294 {
00295   
00296   char buffer[1024];
00297   packet->bufToStr(buffer, sizeof(buffer));
00298 
00299   myCallbackMutex.lock();
00300   if (buffer[0] == '\0')
00301   {
00302     ArLog::log(ArLog::Normal, "%sSaved config to server successfully", myLogPrefix.c_str());
00303     std::list<ArFunctor *>::iterator it;
00304     for (it = mySaveConfigSucceededCBList.begin(); 
00305                it != mySaveConfigSucceededCBList.end(); 
00306                it++)
00307       (*it)->invoke();
00308   }
00309   else
00310   {
00311     ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), buffer);
00312     std::list<ArFunctor1<const char *> *>::iterator it;
00313     for (it = mySaveConfigFailedCBList.begin(); 
00314                it != mySaveConfigFailedCBList.end(); 
00315                it++)
00316       (*it)->invoke(buffer);
00317   }
00318   myCallbackMutex.unlock();
00319 }
00320 
00321 AREXPORT void ArClientHandlerConfig::reloadConfigOnServer(void)
00322 {
00323   myClient->requestOnce("reloadConfig");
00324 }
00325 
00330 AREXPORT ArConfig *ArClientHandlerConfig::getConfig(void)
00331 {
00332   return &myConfig;
00333 }
00334 
00342 AREXPORT ArConfig *ArClientHandlerConfig::getDefaultConfig(void)
00343 {
00344   return myDefaultConfig;
00345 }
00346 
00351 AREXPORT ArConfig ArClientHandlerConfig::getConfigCopy(void)
00352 {
00353   ArConfig copy;
00354   myDataMutex.lock();
00355   copy = myConfig;
00356   myDataMutex.unlock();
00357   return copy;
00358 }
00359 
00360 AREXPORT int ArClientHandlerConfig::lock(void)
00361 {
00362   return myDataMutex.lock();
00363 }
00364 
00365 AREXPORT int ArClientHandlerConfig::tryLock(void)
00366 {
00367   return myDataMutex.tryLock();
00368 }
00369 
00370 AREXPORT int ArClientHandlerConfig::unlock(void)
00371 {
00372   return myDataMutex.unlock();
00373 }
00374 
00375 AREXPORT bool ArClientHandlerConfig::haveGottenConfig(void)
00376 {
00377   bool ret;
00378   myDataMutex.lock();
00379   ret = myHaveGottenConfig;
00380   myDataMutex.unlock();
00381   return ret;
00382 }
00383 
00384 AREXPORT void ArClientHandlerConfig::addGotConfigCB(ArFunctor *functor,
00385                                                     ArListPos::Pos position)
00386 {
00387   myCallbackMutex.lock();
00388   if (position == ArListPos::FIRST)
00389     myGotConfigCBList.push_front(functor);
00390   else if (position == ArListPos::LAST)
00391     myGotConfigCBList.push_back(functor);
00392   else
00393     ArLog::log(ArLog::Terse, 
00394                "ArClientHandlerConfig::addGotConfigCB: Invalid position.");
00395   myCallbackMutex.unlock();
00396 }
00397 
00398 AREXPORT void ArClientHandlerConfig::remGotConfigCB(ArFunctor *functor)
00399 {
00400   myCallbackMutex.lock();
00401   myGotConfigCBList.remove(functor);
00402   myCallbackMutex.unlock();
00403 }
00404 
00405 AREXPORT void ArClientHandlerConfig::addSaveConfigSucceededCB(
00406         ArFunctor *functor, ArListPos::Pos position)
00407 {
00408   myCallbackMutex.lock();
00409   if (position == ArListPos::FIRST)
00410     mySaveConfigSucceededCBList.push_front(functor);
00411   else if (position == ArListPos::LAST)
00412     mySaveConfigSucceededCBList.push_back(functor);
00413   else
00414     ArLog::log(ArLog::Terse, 
00415                "ArClientHandlerConfig::addSaveConfigSucceededCB: Invalid position.");
00416   myCallbackMutex.unlock();
00417 }
00418 
00419 AREXPORT void ArClientHandlerConfig::remSaveConfigSucceededCB(ArFunctor *functor)
00420 {
00421   myCallbackMutex.lock();
00422   mySaveConfigSucceededCBList.remove(functor);
00423   myCallbackMutex.unlock();
00424 }
00425 
00426 
00427 AREXPORT void ArClientHandlerConfig::addSaveConfigFailedCB(
00428         ArFunctor1<const char *> *functor, ArListPos::Pos position)
00429 {
00430   myCallbackMutex.lock();
00431   if (position == ArListPos::FIRST)
00432     mySaveConfigFailedCBList.push_front(functor);
00433   else if (position == ArListPos::LAST)
00434     mySaveConfigFailedCBList.push_back(functor);
00435   else
00436     ArLog::log(ArLog::Terse, 
00437                "ArClientHandlerConfig::addSaveConfigFailedCB: Invalid position.");
00438   myCallbackMutex.unlock();
00439 }
00440 
00441 AREXPORT void ArClientHandlerConfig::remSaveConfigFailedCB(ArFunctor1<const char *> *functor)
00442 {
00443   myCallbackMutex.lock();
00444   mySaveConfigFailedCBList.remove(functor);
00445   myCallbackMutex.unlock();
00446 }
00447 
00448 
00449 AREXPORT void ArClientHandlerConfig::addGotConfigDefaultsCB(
00450         ArFunctor *functor, ArListPos::Pos position)
00451 {
00452   myCallbackMutex.lock();
00453   if (position == ArListPos::FIRST)
00454     myGotConfigDefaultsCBList.push_front(functor);
00455   else if (position == ArListPos::LAST)
00456     myGotConfigDefaultsCBList.push_back(functor);
00457   else
00458     ArLog::log(ArLog::Terse, 
00459                "ArClientHandlerConfig::addGotConfigDefaultsCB: Invalid position.");
00460   myCallbackMutex.unlock();
00461 }
00462 
00463 AREXPORT void ArClientHandlerConfig::remGotConfigDefaultsCB(ArFunctor *functor)
00464 {
00465   myCallbackMutex.lock();
00466   myGotConfigDefaultsCBList.remove(functor);
00467   myCallbackMutex.unlock();
00468 }
00469 
00470 AREXPORT bool ArClientHandlerConfig::haveRequestedDefaults(void)
00471 {
00472   bool ret;
00473   myDataMutex.lock();
00474   ret = myHaveRequestedDefaults || myHaveRequestedDefaultCopy;
00475   myDataMutex.unlock();
00476   return ret;
00477 }
00478 
00479 AREXPORT bool ArClientHandlerConfig::haveGottenDefaults(void)
00480 {
00481   bool ret;
00482   myDataMutex.lock();
00483   ret = myHaveGottenDefaults;
00484   myDataMutex.unlock();
00485   return ret;
00486 }
00487 
00488 AREXPORT bool ArClientHandlerConfig::canRequestDefaults(void)
00489 {
00490   return myClient->dataExists("getConfigDefaults");
00491 }
00492 
00493 AREXPORT bool ArClientHandlerConfig::requestConfigDefaults(void)
00494 {
00495   if (haveRequestedDefaults())
00496   {
00497     ArLog::log(ArLog::Normal, 
00498                "%sRequestConfigDefaults: Cannot request defaults as there are already some being requested",
00499          myLogPrefix.c_str());
00500     return false;
00501   }
00502   if (!canRequestDefaults())
00503   {
00504     ArLog::log(ArLog::Normal, 
00505                "%sRequestConfigDefaults: Defaults requested but not available",
00506          myLogPrefix.c_str());
00507     return false;
00508   }
00509 
00510   ArLog::log(ArLog::Normal, 
00511                    "%sRequesting config reset to default",
00512              myLogPrefix.c_str());
00513 
00514   myDataMutex.lock();
00515   myHaveRequestedDefaults = true;
00516   myHaveGottenDefaults = false;
00517   myHaveRequestedDefaultCopy = false;
00518   myDataMutex.unlock();
00519 
00520   myClient->requestOnce("getConfigDefaults");
00521   return true;
00522 }
00523 
00524 AREXPORT bool ArClientHandlerConfig::requestDefaultConfigFromServer(void)
00525 {
00526   if (haveRequestedDefaults())
00527   {
00528     ArLog::log(ArLog::Normal, 
00529                "%sRequestConfigDefaults: Cannot request defaults as there are already some being requested",
00530          myLogPrefix.c_str());
00531     return false;
00532   }
00533   if (!canRequestDefaults())
00534   {
00535     ArLog::log(ArLog::Normal, 
00536                "%sRequestConfigDefaults: Defaults requested but not available",
00537          myLogPrefix.c_str());
00538     return false;
00539   }
00540 
00541   
00542   myDataMutex.lock();
00543 
00544   myHaveRequestedDefaults = false;
00545   myHaveGottenDefaults = false;
00546   myHaveRequestedDefaultCopy = true;
00547   myDataMutex.unlock();
00548 
00549   myClient->requestOnce("getConfigDefaults");
00550   return true;
00551 }
00552 
00553 AREXPORT bool ArClientHandlerConfig::requestSectionDefaults(
00554         const char *section)
00555 {
00556   if (haveRequestedDefaults())
00557   {
00558     ArLog::log(ArLog::Normal, 
00559                "RequestSectionDefaults: Cannot request defaults as there are already some being requested");
00560     return false;
00561   }
00562   if (!canRequestDefaults())
00563   {
00564     ArLog::log(ArLog::Normal, 
00565                "%sRequestSectionDefaults: Defaults requested but not available",
00566          myLogPrefix.c_str());
00567     return false;
00568   }
00569   myDataMutex.lock();
00570   if (myConfig.findSection(section) == NULL)
00571   {
00572     ArLog::log(ArLog::Normal, 
00573                "%sRequestSectionDefaults: Section '%s' requested but doesn't exist", 
00574          myLogPrefix.c_str(), section);
00575     myDataMutex.unlock();
00576     return false;
00577   }
00578 
00579   ArLog::log(ArLog::Normal, 
00580                    "%sRequesting config section %s reset to default",
00581              myLogPrefix.c_str(),
00582              section);
00583 
00584   myHaveRequestedDefaults = true;
00585   myHaveGottenDefaults = false;
00586   myHaveRequestedDefaultCopy = false;
00587   myDataMutex.unlock();
00588   myClient->requestOnceWithString("getConfigDefaults", section);
00589   return true;
00590 }
00591 
00592 
00593 
00594 AREXPORT void ArClientHandlerConfig::handleGetConfigDefaults(
00595         ArNetPacket *packet)
00596 {
00597   ArLog::log(ArLog::Normal, "%sreceived default config %s", 
00598                              myLogPrefix.c_str(), 
00599                  ((myHaveRequestedDefaultCopy) ? "(copy)" : "(reset)"));
00600 
00601   char param[1024];
00602   char argument[1024];
00603   char errorBuffer[1024];
00604   
00605   myDataMutex.lock();
00606 
00607   ArConfig *config = NULL;
00608 
00609   // If the config (or a section) is being reset to its default values,
00610   // then we don't want to remove any parameters that are not set -- i.e.
00611   // any parameters that are not contained in the default config.
00612   bool isClearUnsetValues = false;
00613 
00614   if (myHaveRequestedDefaults) {
00615 
00616     config = &myConfig;
00617   }
00618   else if (myHaveRequestedDefaultCopy) {
00619 
00620     // If we have requested a copy of the default configuration, then we
00621     // will want to remove any parameters that haven't been explicitly set.
00622     // (This is because of the next line, which copies the current config 
00623     // to the default config.)
00624     isClearUnsetValues = true;
00625 
00626     // The default config is transmitted in an "abbreviated" form -- just 
00627     // the section/param names and values.  Copy the current config to the
00628     // default before processing the packet so that the parameter types, etc.
00629     // can be preserved.
00630     if (myDefaultConfig == NULL) {
00631       myDefaultConfig = new ArConfig(myConfig);
00632       myDefaultConfig->setConfigName("Default", myRobotName.c_str());
00633     }
00634     else {
00635       *myDefaultConfig = myConfig;
00636     }
00637 
00638 
00639     config = myDefaultConfig;
00640   }
00641   // if we didn't ask for any of these, then just return since the
00642   // data is for someone else
00643   else
00644   {
00645     myDataMutex.unlock();
00646     return;
00647   }
00648 
00649   if (config == NULL) {
00650     ArLog::log(ArLog::Normal,
00651                "ArClientHandlerConfig error determining config to populate with default values");
00652   myDataMutex.unlock();
00653     return;
00654   }
00655 
00656   ArArgumentBuilder *builder = NULL;
00657   ArLog::log(ArLog::Normal, "Got defaults");
00658   errorBuffer[0] = '\0';
00659   
00660   //myDataMutex.lock();
00661   if (isClearUnsetValues) {
00662     config->clearAllValueSet();
00663   }
00664 
00665   while (packet->getDataReadLength() < packet->getDataLength())
00666   {
00667     packet->bufToStr(param, sizeof(param));  
00668     packet->bufToStr(argument, sizeof(argument));  
00669 
00670 
00671     builder = new ArArgumentBuilder;
00672     builder->setExtraString(param);
00673     builder->add(argument);
00674 
00675     if ((strcasecmp(param, "Section") == 0 && 
00676         !config->parseSection(builder, errorBuffer, sizeof(errorBuffer))) ||
00677         (strcasecmp(param, "Section") != 0 &&
00678         !config->parseArgument(builder, errorBuffer, sizeof(errorBuffer))))
00679     {
00680       ArLog::log(ArLog::Terse, "%sArClientHandlerConfig::handleGetConfigDefaults: Hideous problem getting defaults, couldn't parse '%s %s'", 
00681                              myLogPrefix.c_str(), param, argument);
00682     }
00683     else {
00684       IFDEBUG(if (strlen(param) > 0) {
00685                ArLog::log(ArLog::Normal, "%sArClientHandlerConfig::handleGetConfigDefaults: added default '%s %s'", 
00686                  myLogPrefix.c_str(), param, argument); } );
00687     }
00688     delete builder;
00689     builder = NULL;
00690   }
00691   myHaveRequestedDefaults = false;
00692   myHaveRequestedDefaultCopy = false;
00693   myHaveGottenDefaults = true;
00694 
00695   if (isClearUnsetValues) {
00696     config->removeAllUnsetValues();
00697   }
00698 
00699   IFDEBUG(config->log());
00700 
00701   myDataMutex.unlock();
00702 
00703   myCallbackMutex.lock();
00704   std::list<ArFunctor *>::iterator it;
00705   for (it = myGotConfigDefaultsCBList.begin(); 
00706        it != myGotConfigDefaultsCBList.end(); 
00707        it++)
00708     (*it)->invoke();
00709   myCallbackMutex.unlock();
00710 }
00711 

Generated on Tue Feb 20 10:51:49 2007 for ArNetworking by  doxygen 1.4.0