SolarisPlatformUtils.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:20k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: SolarisPlatformUtils.cpp,v 1.14 2003/05/15 18:37:49 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #if !defined (APP_NO_THREADS)
  63. #  if defined (XML_USE_DCE)
  64. #    include  <dce/pthread.h>
  65. #  else
  66. #    include    <pthread.h>
  67. #  endif
  68. #endif // APP_NO_THREADS
  69. #include    <unistd.h>
  70. #include    <stdio.h>
  71. #include    <stdlib.h>
  72. #include    <errno.h>
  73. #include    <libgen.h>
  74. #include    <sys/timeb.h>
  75. #include    <string.h>
  76. #include    <link.h>
  77. #include    <limits.h>
  78. #include    <dlfcn.h>
  79. #include    <xercesc/util/Janitor.hpp>
  80. #include    <xercesc/util/PlatformUtils.hpp>
  81. #include    <xercesc/util/RuntimeException.hpp>
  82. #include    <xercesc/util/Mutexes.hpp>
  83. #include    <xercesc/util/XMLString.hpp>
  84. #include    <xercesc/util/XMLUniDefs.hpp>
  85. #include    <xercesc/util/XMLUni.hpp>
  86. #include    <xercesc/util/PanicHandler.hpp>
  87. #if defined (XML_USE_ICU_TRANSCODER)
  88.     #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
  89. #else   // use native transcoder
  90.     #include <xercesc/util/Transcoders/Iconv/IconvTransService.hpp>
  91. #endif
  92. #if defined (XML_USE_ICU_MESSAGELOADER)
  93.     #include <xercesc/util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  94. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  95.     #include <xercesc/util/MsgLoaders/MsgCatalog/MsgCatalogLoader.hpp>
  96. #else   // use In-memory message loader
  97.     #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  98. #endif
  99. #if defined (XML_USE_NETACCESSOR_SOCKET)
  100.     #include <xercesc/util/NetAccessors/Socket/SocketNetAccessor.hpp>
  101. #endif
  102. #if defined (SOLARIS)
  103. extern "C" int ftime(struct timeb *); // Solaris headers missing this decl
  104. #endif
  105. XERCES_CPP_NAMESPACE_BEGIN
  106. // ---------------------------------------------------------------------------
  107. //  XMLPlatformUtils: Private Static Methods
  108. // ---------------------------------------------------------------------------
  109. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  110. {
  111. #if defined (XML_USE_NETACCESSOR_SOCKET)
  112.     return new SocketNetAccessor();
  113. #else
  114.     return 0;
  115. #endif
  116. }
  117. //
  118. //  This method is called by the platform independent part of this class
  119. //  when client code asks to have one of the supported message sets loaded.
  120. //  In our case, we use the ICU based message loader mechanism.
  121. //
  122. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  123. {
  124.     XMLMsgLoader* retVal;
  125.     try
  126.     {
  127. #if defined (XML_USE_ICU_MESSAGELOADER)
  128.         retVal = new ICUMsgLoader(msgDomain);
  129. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  130.         retVal = new MsgCatalogLoader(msgDomain);
  131. #else
  132.         retVal = new InMemMsgLoader(msgDomain);
  133. #endif
  134.     }
  135.     catch(...)
  136.     {
  137.         panic(PanicHandler::Panic_CantLoadMsgDomain);
  138.     }
  139.     return retVal;
  140. }
  141. //
  142. //  This method is called very early in the bootstrapping process. This guy
  143. //  must create a transcoding service and return it. It cannot use any string
  144. //  methods, any transcoding services, throw any exceptions, etc... It just
  145. //  makes a transcoding service and returns it, or returns zero on failure.
  146. //
  147. XMLTransService* XMLPlatformUtils::makeTransService()
  148. #if defined (XML_USE_ICU_TRANSCODER)
  149. {
  150.     return new ICUTransService;
  151. }
  152. #elif defined (XML_USE_ICONV_TRANSCODER)
  153. {
  154.     return new IconvTransService;
  155. }
  156. #else // Use Native transcoding service
  157. {
  158.     return new IconvTransService;
  159. }
  160. #endif
  161. // ---------------------------------------------------------------------------
  162. //  XMLPlatformUtils: The panic method
  163. // ---------------------------------------------------------------------------
  164. void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason)
  165. {
  166.     fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason);
  167. }
  168. // ---------------------------------------------------------------------------
  169. //  XMLPlatformUtils: File Methods
  170. // ---------------------------------------------------------------------------
  171. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  172. {
  173.     // Get the current position
  174.     int curPos = ftell( (FILE*)theFile);
  175.     if (curPos == -1)
  176.         ThrowXML(XMLPlatformUtilsException,
  177.                  XMLExcepts::File_CouldNotGetSize);
  178.     return (unsigned int)curPos;
  179. }
  180. void XMLPlatformUtils::closeFile(FileHandle theFile)
  181. {
  182.     if (fclose((FILE*) theFile))
  183.         ThrowXML(XMLPlatformUtilsException,
  184.                  XMLExcepts::File_CouldNotCloseFile);
  185. }
  186. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  187. {
  188.     // Get the current position
  189.     long  int curPos = ftell((FILE*) theFile);
  190.     if (curPos == -1)
  191.         ThrowXML(XMLPlatformUtilsException,
  192.                  XMLExcepts::File_CouldNotGetCurPos);
  193.     // Seek to the end and save that value for return
  194.     if (fseek( (FILE*) theFile, 0, SEEK_END) )
  195.         ThrowXML(XMLPlatformUtilsException,
  196.                  XMLExcepts::File_CouldNotSeekToEnd);
  197.     long int retVal = ftell((FILE*) theFile);
  198.     if (retVal == -1)
  199.         ThrowXML(XMLPlatformUtilsException,
  200.                  XMLExcepts::File_CouldNotSeekToEnd);
  201.     // And put the pointer back
  202.     if (fseek((FILE*) theFile, curPos, SEEK_SET))
  203.         ThrowXML(XMLPlatformUtilsException,
  204.                  XMLExcepts::File_CouldNotSeekToPos);
  205.     return (unsigned int)retVal;
  206. }
  207. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  208. {
  209.     FileHandle retVal = (FILE*)fopen( fileName , "rb" );
  210.     if (retVal == NULL)
  211.         return 0;
  212.     return retVal;
  213. }
  214. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  215. {
  216.     const char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  217.     ArrayJanitor<char> janText((char*)tmpFileName, fgMemoryManager);
  218.     FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" );
  219.     if (retVal == NULL)
  220.         return 0;
  221.     return retVal;
  222. }
  223. FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  224. {
  225.     const char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  226.     ArrayJanitor<char> janText((char*)tmpFileName, fgMemoryManager);
  227.     return fopen( tmpFileName , "wb" );
  228. }
  229. FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  230. {
  231.     return fopen( fileName , "wb" );
  232. }
  233. unsigned int
  234. XMLPlatformUtils::readFileBuffer(FileHandle              theFile
  235.                                , const unsigned int      toRead
  236.                                , XMLByte* const          toFill)
  237. {
  238.     size_t noOfItemsRead =
  239.                fread((void*) toFill, 1, toRead, (FILE*) theFile);
  240.     if(ferror((FILE*) theFile))
  241.     {
  242.         ThrowXML(XMLPlatformUtilsException,
  243.                  XMLExcepts::File_CouldNotReadFromFile);
  244.     }
  245.     return (unsigned int) noOfItemsRead;
  246. }
  247. void
  248. XMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile
  249.                                    , long                  toWrite
  250.                                    , const XMLByte* const  toFlush)
  251. {
  252.     if (!theFile        ||
  253.         (toWrite <= 0 ) ||
  254.         !toFlush         )
  255.         return;
  256.     const XMLByte* tmpFlush = (const XMLByte*) toFlush;
  257.     size_t bytesWritten = 0;
  258.     while (true)
  259.     {
  260.         bytesWritten=fwrite(tmpFlush, sizeof(XMLByte), toWrite, (FILE*)theFile);
  261.         if(ferror((FILE*)theFile))
  262.         {
  263.             ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  264.         }
  265.         if (bytesWritten < toWrite) //incomplete write
  266.         {
  267.             tmpFlush+=bytesWritten;
  268.             toWrite-=bytesWritten;
  269.             bytesWritten=0;
  270.         }
  271.         else
  272.             return;
  273.     }
  274.     return;
  275. }
  276. void XMLPlatformUtils::resetFile(FileHandle theFile)
  277. {
  278.     // Seek to the start of the file
  279.     if (fseek((FILE*) theFile, 0, SEEK_SET))
  280.         ThrowXML(XMLPlatformUtilsException,
  281.                  XMLExcepts::File_CouldNotResetFile);
  282. }
  283. // ---------------------------------------------------------------------------
  284. //  XMLPlatformUtils: File system methods
  285. // ---------------------------------------------------------------------------
  286. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath,
  287.                                      MemoryManager* const manager)
  288. {
  289.     //
  290.     //  NOTE: THe path provided has always already been opened successfully,
  291.     //  so we know that its not some pathological freaky path. It comes in
  292.     //  in native format, and goes out as Unicode always
  293.     //
  294.     char* newSrc = XMLString::transcode(srcPath, fgMemoryManager);
  295.     ArrayJanitor<char> janText(newSrc, fgMemoryManager);
  296.     // Use a local buffer that is big enough for the largest legal path
  297.     char absPath[PATH_MAX + 1];
  298.     //get the absolute path
  299.     char* retPath = realpath(newSrc, &absPath[0]);
  300.     if (!retPath)
  301.     {
  302.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  303.     }
  304.     return XMLString::transcode(absPath, manager);
  305. }
  306. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  307. {
  308.     // Check for pathological case of empty path
  309.     if (!toCheck[0])
  310.         return false;
  311.     //
  312.     //  If it starts with a slash, then it cannot be relative. This covers
  313.     //  both something like "TestFile.xml" and an NT Lan type remote path
  314.     //  that starts with a node like "\MyNodeTestFile.xml".
  315.     //
  316.     if (toCheck[0] == XMLCh('/'))
  317.         return false;
  318.     // Else assume its a relative path
  319.     return true;
  320. }
  321. XMLCh* XMLPlatformUtils::getCurrentDirectory(MemoryManager* const manager)
  322. {
  323.     char  dirBuf[PATH_MAX + 1];
  324.     char  *curDir = getcwd(&dirBuf[0], PATH_MAX + 1);
  325.     if (!curDir)
  326.     {
  327.         ThrowXML(XMLPlatformUtilsException,
  328.                  XMLExcepts::File_CouldNotGetBasePathName);
  329.     }
  330.     return XMLString::transcode(curDir, manager);
  331. }
  332. inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
  333. {
  334.     return ( chBackSlash == c || chForwardSlash == c);
  335. }
  336. // ---------------------------------------------------------------------------
  337. //  XMLPlatformUtils: Timing Methods
  338. // ---------------------------------------------------------------------------
  339. unsigned long XMLPlatformUtils::getCurrentMillis()
  340. {
  341.     timeb aTime;
  342.     ftime(&aTime);
  343.     return (unsigned long)(aTime.time*1000 + aTime.millitm);
  344. }
  345. // -----------------------------------------------------------------------
  346. //  Mutex methods
  347. // -----------------------------------------------------------------------
  348. #if !defined (APP_NO_THREADS)
  349. // ---------------------------------------------------------------------------
  350. //  XMLPlatformUtils: Platform init method
  351. // ---------------------------------------------------------------------------
  352. static pthread_mutex_t* gAtomicOpMutex =0 ;
  353. void XMLPlatformUtils::platformInit()
  354. {
  355.     //
  356.     // The gAtomicOpMutex mutex needs to be created
  357.     // because compareAndSwap and incrementlocation and decrementlocation
  358.     // does not have the atomic system calls for usage
  359.     // Normally, mutexes are created on first use, but there is a
  360.     // circular dependency between compareAndExchange() and
  361.     // mutex creation that must be broken.
  362.     gAtomicOpMutex = new pthread_mutex_t;
  363. #if defined(XML_USE_DCE)
  364.     if (pthread_mutex_init(gAtomicOpMutex, pthread_mutexattr_default)) {
  365. delete gAtomicOpMutex;
  366. gAtomicOpMutex = 0;
  367.         panic( PanicHandler::Panic_SystemInit );
  368.     }
  369. #else // XML_USE_DCE
  370.     if (pthread_mutex_init(gAtomicOpMutex, NULL)) {
  371. delete gAtomicOpMutex;
  372. gAtomicOpMutex = 0;
  373.         panic( PanicHandler::Panic_SystemInit );
  374.     }
  375. #endif // XML_USE_DCE
  376. }
  377. #ifndef XML_USE_DCE
  378. // inlining the class with dce threading causes segmentation fault
  379. class  RecursiveMutex
  380. {
  381. public:
  382.     pthread_mutex_t   mutex;
  383.     int               recursionCount;
  384.     pthread_t         tid;
  385.     RecursiveMutex() {
  386.                if (pthread_mutex_init(&mutex, NULL))
  387.                 ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotCreate);
  388.                        recursionCount = 0;
  389.                        tid = 0;
  390.                      };
  391.     ~RecursiveMutex() {
  392.             if (pthread_mutex_destroy(&mutex))
  393.                 ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy);
  394.                       };
  395.      void lock()      {
  396.               if (pthread_equal(tid, pthread_self()))
  397.               {
  398.                   recursionCount++;
  399.                   return;
  400.               }
  401.               if (pthread_mutex_lock(&mutex) != 0)
  402.                   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotLock);
  403.               tid = pthread_self();
  404.               recursionCount = 1;
  405.               };
  406.      void unlock()    {
  407.                           if (--recursionCount > 0)
  408.                               return;
  409.               if (pthread_mutex_unlock(&mutex) != 0)
  410.                   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotUnlock);
  411.                           tid = 0;
  412.                        };
  413.    };
  414. #endif // ifndef XML_USE_DCE
  415. void* XMLPlatformUtils::makeMutex()
  416. {
  417. #if defined(XML_USE_DCE)
  418.     pthread_mutex_t* mutex = new pthread_mutex_t;
  419.     if (mutex ==  NULL)
  420.     {
  421.         ThrowXML(XMLPlatformUtilsException,
  422.                  XMLExcepts::Mutex_CouldNotCreate);
  423.     }
  424.     pthread_mutexattr_t attr;
  425.     pthread_mutexattr_create(&attr);
  426.     pthread_mutexattr_setkind_np(&attr, MUTEX_RECURSIVE_NP);
  427.     if (pthread_mutex_init(mutex, attr))
  428.     {
  429.         ThrowXML(XMLPlatformUtilsException,
  430.                  XMLExcepts::Mutex_CouldNotCreate);
  431.     }
  432.     pthread_mutexattr_delete(&attr);
  433.     return (void*)(mutex);
  434. #else
  435.     return new RecursiveMutex;
  436. #endif
  437. };
  438. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  439. {
  440.     if (mtxHandle == NULL)
  441.         return;
  442. #if defined(XML_USE_DCE)
  443.     pthread_mutex_t *rm = (pthread_mutex_t *)mtxHandle;
  444.     pthread_mutex_destroy(rm);
  445. #else
  446.     RecursiveMutex *rm = (RecursiveMutex *)mtxHandle;
  447. #endif
  448.     delete rm;
  449. };
  450. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  451. {
  452.     if (mtxHandle == NULL)
  453.         return;
  454. #if defined(XML_USE_DCE)
  455.     pthread_mutex_t *rm = (pthread_mutex_t *)mtxHandle;
  456.     pthread_mutex_lock(rm);
  457. #else
  458.     RecursiveMutex *rm = (RecursiveMutex *)mtxHandle;
  459.     rm->lock();
  460. #endif
  461. }
  462. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  463. {
  464.     if (mtxHandle == NULL)
  465.         return;
  466. #if defined(XML_USE_DCE)
  467.     pthread_mutex_t *rm = (pthread_mutex_t *)mtxHandle;
  468.     pthread_mutex_unlock(rm);
  469. #else
  470.     RecursiveMutex *rm = (RecursiveMutex *)mtxHandle;
  471.     rm->unlock();
  472. #endif
  473. }
  474. // -----------------------------------------------------------------------
  475. //  Miscellaneous synchronization methods
  476. // -----------------------------------------------------------------------
  477. //atomic system calls in Solaris is only restricted to kernel libraries
  478. //So, to make operations thread safe we implement static mutex and lock
  479. //the atomic operations. It makes the process slow but what's the alternative!
  480. void* XMLPlatformUtils::compareAndSwap ( void**      toFill ,
  481.                     const void* const newValue ,
  482.                     const void* const toCompare)
  483. {
  484.     //return ((void*)cas32( (uint32_t*)toFill,  (uint32_t)toCompare, (uint32_t)newValue) );
  485.     // the below calls are temporarily made till the above functions are part of user library
  486.     // Currently its supported only in the kernel mode
  487.     if (pthread_mutex_lock( gAtomicOpMutex))
  488.         panic(PanicHandler::Panic_SynchronizationErr);
  489.     void *retVal = *toFill;
  490.     if (*toFill == toCompare)
  491.               *toFill = (void *)newValue;
  492.     if (pthread_mutex_unlock( gAtomicOpMutex))
  493.         panic(PanicHandler::Panic_SynchronizationErr);
  494.     return retVal;
  495. }
  496. int XMLPlatformUtils::atomicIncrement(int &location)
  497. {
  498.     //return (int)atomic_add_32_nv( (uint32_t*)&location, 1);
  499.     if (pthread_mutex_lock( gAtomicOpMutex))
  500.         panic(PanicHandler::Panic_SynchronizationErr);
  501.     int tmp = ++location;
  502.     if (pthread_mutex_unlock( gAtomicOpMutex))
  503.         panic(PanicHandler::Panic_SynchronizationErr);
  504.     return tmp;
  505. }
  506. int XMLPlatformUtils::atomicDecrement(int &location)
  507. {
  508.     //return (int)atomic_add_32_nv( (uint32_t*)&location, -1);
  509.     if (pthread_mutex_lock( gAtomicOpMutex))
  510.         panic(PanicHandler::Panic_SynchronizationErr);
  511.     int tmp = --location;
  512.     if (pthread_mutex_unlock( gAtomicOpMutex))
  513.         panic(PanicHandler::Panic_SynchronizationErr);
  514.     return tmp;
  515. }
  516. #else // #if !defined (APP_NO_THREADS)
  517. void XMLPlatformUtils::platformInit()
  518. {
  519. }
  520. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  521. {
  522. }
  523. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  524. {
  525. }
  526. void* XMLPlatformUtils::makeMutex()
  527. {
  528.         return 0;
  529. }
  530. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  531. {
  532. }
  533. void* XMLPlatformUtils::compareAndSwap ( void**      toFill,
  534.                                    const void* const newValue,
  535.                                    const void* const toCompare)
  536. {
  537.     void *retVal = *toFill;
  538.     if (*toFill == toCompare)
  539.        *toFill = (void *)newValue;
  540.     return retVal;
  541. }
  542. int XMLPlatformUtils::atomicIncrement(int &location)
  543. {
  544.     return ++location;
  545. }
  546. int XMLPlatformUtils::atomicDecrement(int &location)
  547. {
  548.     return --location;
  549. }
  550. #endif // APP_NO_THREADS
  551. FileHandle XMLPlatformUtils::openStdInHandle()
  552. {
  553.         return (FileHandle)fdopen(dup(0), "rb");
  554. }
  555. void XMLPlatformUtils::platformTerm()
  556. {
  557. #if !defined(APP_NO_THREADS)
  558. pthread_mutex_destroy(gAtomicOpMutex);
  559.     delete gAtomicOpMutex;
  560. gAtomicOpMutex = 0;
  561. #endif
  562. }
  563. #include <xercesc/util/LogicalPath.c>
  564. XERCES_CPP_NAMESPACE_END