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

词法分析

开发平台:

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.  * $Log: LinuxPlatformUtils.cpp,v $
  58.  * Revision 1.16  2003/05/15 18:37:48  knoaman
  59.  * Partial implementation of the configurable memory manager.
  60.  *
  61.  * Revision 1.15  2003/04/25 17:19:53  peiyongz
  62.  * throw exception if getcwd() fails
  63.  *
  64.  * Revision 1.14  2003/04/24 02:54:46  peiyongz
  65.  * Logical Path Resolution
  66.  *
  67.  * Revision 1.13  2003/04/21 04:28:45  peiyongz
  68.  * performance tuning
  69.  *
  70.  * Revision 1.12  2003/03/09 16:56:11  peiyongz
  71.  * PanicHandler
  72.  *
  73.  * Revision 1.11  2003/02/05 18:27:34  tng
  74.  * [Bug 13437] Incorrect memory management in LinuxPlatformUtils.cpp.  Fixed by Adam Zell.
  75.  *
  76.  * Revision 1.10  2002/12/02 19:16:46  tng
  77.  * [Bug 14723] Memory leak in atomicOpsMutex.  Patch from Adam Zell.
  78.  *
  79.  * Revision 1.9  2002/11/07 22:38:13  peiyongz
  80.  * build -miconv on hpux and linux
  81.  *
  82.  * Revision 1.8  2002/11/04 15:13:00  tng
  83.  * C++ Namespace Support.
  84.  *
  85.  * Revision 1.7  2002/08/19 19:38:17  tng
  86.  * [Bug 11771] Linux specific IconvGNU transcoder.  Patch from Vasily Tchekalkin.
  87.  *
  88.  * Revision 1.6  2002/07/15 21:53:04  peiyongz
  89.  * CouldNotWriteToFile
  90.  *
  91.  * Revision 1.5  2002/06/24 15:55:21  peiyongz
  92.  * Change from James Berry( jberry@criticalpath.com)
  93.  *
  94.  * Revision 1.4  2002/06/20 15:28:08  peiyongz
  95.  * Fix to compilation error
  96.  *
  97.  * Revision 1.2  2002/05/21 20:31:47  tng
  98.  * Minor update: Remove obsolete code
  99.  *
  100.  * Revision 1.1.1.1  2002/02/01 22:22:24  peiyongz
  101.  * sane_include
  102.  *
  103.  * Revision 1.22  2001/10/25 15:36:35  tng
  104.  * [Bug 4318] Single threaded build fails due to obsolete #define .
  105.  *
  106.  * Revision 1.21  2001/10/25 15:20:31  tng
  107.  * Need to guard with NO_APP_THREADS when destroying the mutex.
  108.  *
  109.  * Revision 1.20  2001/10/23 23:10:48  peiyongz
  110.  * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  111.  *
  112.  * Revision 1.19  2001/05/11 12:03:40  tng
  113.  * Need to add header <linux/limits> for definition of PATH_MAX
  114.  *
  115.  * Revision 1.18  2001/05/10 20:40:44  lehors
  116.  * built-in buffer limit could be smaller than system limit,
  117.  * we now use PATH_MAX instead - patch from Christian Schuhegger - bug #1158
  118.  *
  119.  * Revision 1.17  2000/07/25 22:29:55  aruna1
  120.  * Char definitions in XMLUni moved to XMLUniDefs
  121.  *
  122.  * Revision 1.16  2000/03/24 00:13:03  aruna1
  123.  * Platform initialization taken care for both threaded and non-threaded environment
  124.  *
  125.  * Revision 1.15  2000/03/20 23:48:52  rahulj
  126.  * Added Socket based NetAccessor. This will enable one to
  127.  * use HTTP URL's for system id's. Default build options do
  128.  * not use this NetAccessor. Specify the '-n socket' option
  129.  * to 'runConfigure' to configure Xerces-C to use this new
  130.  * feature. The code works under Solaris 2.6, Linux, AIX
  131.  * and HPUX 11 with aCC.
  132.  * Todo's: enable proper error handling.
  133.  *
  134.  * Revision 1.14  2000/03/18 00:00:00  roddey
  135.  * Initial updates for two way transcoding support
  136.  *
  137.  * Revision 1.13  2000/03/02 21:10:36  abagchi
  138.  * Added empty function platformTerm()
  139.  *
  140.  * Revision 1.12  2000/03/02 20:42:41  abagchi
  141.  * Fixed typo in XMLExcepts
  142.  *
  143.  * Revision 1.11  2000/03/02 19:55:24  roddey
  144.  * This checkin includes many changes done while waiting for the
  145.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  146.  * available elsewhere.
  147.  *
  148.  * Revision 1.10  2000/02/22 00:58:15  aruna1
  149.  * openFile API updated
  150.  *
  151.  * Revision 1.9  2000/02/06 07:48:28  rahulj
  152.  * Year 2K copyright swat.
  153.  *
  154.  * Revision 1.8  2000/01/25 22:32:56  aruna1
  155.  * Updated panic information
  156.  *
  157.  * Revision 1.7  2000/01/19 23:21:37  abagchi
  158.  * Made this file compatible with ICU 1.4
  159.  *
  160.  * Revision 1.6  2000/01/19 17:37:48  abagchi
  161.  * Removed the streaming classes
  162.  *
  163.  * Revision 1.5  2000/01/14 02:04:43  abagchi
  164.  * Introduced getFullPath() and weavePath()
  165.  *
  166.  * Revision 1.4  1999/12/14 23:53:33  rahulj
  167.  * Removed the offending Ctrl-M's from the commit message
  168.  * logs which was giving packaging problems.
  169.  *
  170.  * PR:
  171.  * Obtained from:
  172.  * Submitted by:
  173.  * Reviewed by:
  174.  *
  175.  * Revision 1.3  1999/11/23 02:00:48  rahulj
  176.  * Code now works under HPUX 11. Tested inmemory message loader.
  177.  * Revamped makefiles. Builds with both DCE threads as well as pthread libraries.
  178.  *
  179.  * Revision 1.2  1999/11/17 22:35:33  rahulj
  180.  * Replaced default attr mutexes with recursive mutexes. Also code works with ICU transcoding service
  181.  *
  182.  * Revision 1.1.1.1  1999/11/09 01:07:01  twl
  183.  * Initial checkin
  184.  *
  185.  * Revision 1.6  1999/11/08 20:45:30  rahul
  186.  * Swat for adding in Product name and CVS comment log variable.
  187.  *
  188.  */
  189. // ---------------------------------------------------------------------------
  190. //  Includes
  191. // ---------------------------------------------------------------------------
  192. #if !defined(APP_NO_THREADS)
  193. #include    <pthread.h>
  194. #endif
  195. #ifndef _GNU_SOURCE
  196.     #error _GNU_SOURCE is not defined in your compile settings
  197. #endif
  198. #include    <unistd.h>
  199. #include    <stdio.h>
  200. #include    <stdlib.h>
  201. #include    <errno.h>
  202. #include    <libgen.h>
  203. #include    <linux/limits.h>           //for PATH_MAX
  204. #include    <sys/timeb.h>
  205. #include    <string.h>
  206. #include    <xercesc/util/PlatformUtils.hpp>
  207. #include    <xercesc/util/RuntimeException.hpp>
  208. #include    <xercesc/util/Janitor.hpp>
  209. #include    <xercesc/util/Mutexes.hpp>
  210. #include    <xercesc/util/XMLString.hpp>
  211. #include    <xercesc/util/XMLUniDefs.hpp>
  212. #include    <xercesc/util/XMLUni.hpp>
  213. #include    <xercesc/util/PanicHandler.hpp>
  214. #if defined(XML_USE_ICU_TRANSCODER)
  215.     #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
  216. #elif defined (XML_USE_GNU_TRANSCODER)
  217.     #include <xercesc/util/Transcoders/IconvGNU/IconvGNUTransService.hpp>
  218. #else
  219.     // Use native transcoder. Same as -DXML_USE_NATIVE_TRANSCODER
  220.     #include <xercesc/util/Transcoders/Iconv/IconvTransService.hpp>
  221. #endif
  222. #if defined(XML_USE_ICU_MESSAGELOADER)
  223.     #include <xercesc/util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  224. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  225.     #include <xercesc/util/MsgLoaders/MsgCatalog/MsgCatalogLoader.hpp>
  226. #else
  227.     // Same as -DXML_USE_INMEM_MESSAGELOADER
  228.     #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  229. #endif
  230. #if defined (XML_USE_NETACCESSOR_SOCKET)
  231.     #include <xercesc/util/NetAccessors/Socket/SocketNetAccessor.hpp>
  232. #endif
  233. XERCES_CPP_NAMESPACE_BEGIN
  234. // ---------------------------------------------------------------------------
  235. //  XMLPlatformUtils: Private Static Methods
  236. // ---------------------------------------------------------------------------
  237. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  238. {
  239. #if defined (XML_USE_NETACCESSOR_SOCKET)
  240.     return new SocketNetAccessor();
  241. #else
  242.     return 0;
  243. #endif
  244. }
  245. //
  246. //  This method is called by the platform independent part of this class
  247. //  when client code asks to have one of the supported message sets loaded.
  248. //
  249. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  250. {
  251.     XMLMsgLoader* retVal;
  252.     try
  253.     {
  254. #if defined (XML_USE_ICU_MESSAGELOADER)
  255.         retVal = new ICUMsgLoader(msgDomain);
  256. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  257.         retVal = new MsgCatalogLoader(msgDomain);
  258. #else
  259.         // same as -DXML_USE_INMEM_MESSAGELOADER
  260.         retVal = new InMemMsgLoader(msgDomain);
  261. #endif
  262.     }
  263.     catch(...)
  264.     {
  265.         panic(PanicHandler::Panic_CantLoadMsgDomain);
  266.     }
  267.     return retVal;
  268. }
  269. //
  270. //  This method is called very early in the bootstrapping process. This guy
  271. //  must create a transcoding service and return it. It cannot use any string
  272. //  methods, any transcoding services, throw any exceptions, etc... It just
  273. //  makes a transcoding service and returns it, or returns zero on failure.
  274. //
  275. XMLTransService* XMLPlatformUtils::makeTransService()
  276. {
  277. #if defined (XML_USE_ICU_TRANSCODER)
  278.     // Use ICU transcoding services.
  279.     // same as -DXML_USE_ICU_MESSAGELOADER
  280.     return new ICUTransService;
  281. #elif defined (XML_USE_GNU_TRANSCODER)
  282.     return new IconvGNUTransService;
  283. #else
  284.     // Use native transcoding services.
  285.     // same as -DXML_USE_NATIVE_TRANSCODER
  286.     return new IconvTransService;
  287. #endif
  288. }
  289. // ---------------------------------------------------------------------------
  290. //  XMLPlatformUtils: The panic method
  291. // ---------------------------------------------------------------------------
  292. void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason)
  293. {
  294.     fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason);
  295. }
  296. // ---------------------------------------------------------------------------
  297. //  XMLPlatformUtils: File Methods
  298. // ---------------------------------------------------------------------------
  299. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  300. {
  301.     int curPos = ftell( (FILE*)theFile);
  302.     if (curPos == -1)
  303.         ThrowXML(XMLPlatformUtilsException,
  304.                  XMLExcepts::File_CouldNotGetSize);
  305.     return (unsigned int)curPos;
  306. }
  307. void XMLPlatformUtils::closeFile(FileHandle theFile)
  308. {
  309.     if (fclose((FILE*)theFile))
  310.         ThrowXML(XMLPlatformUtilsException,
  311.                  XMLExcepts::File_CouldNotCloseFile);
  312. }
  313. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  314. {
  315.     // Get the current position
  316.     long  int curPos = ftell((FILE*) theFile);
  317.     if (curPos == -1)
  318.         ThrowXML(XMLPlatformUtilsException,
  319.                  XMLExcepts::File_CouldNotGetCurPos);
  320.     // Seek to the end and save that value for return
  321.      if (fseek((FILE*) theFile, 0, SEEK_END))
  322.         ThrowXML(XMLPlatformUtilsException,
  323.                  XMLExcepts::File_CouldNotSeekToEnd);
  324.     long int retVal = ftell((FILE*)theFile);
  325.     if (retVal == -1)
  326.         ThrowXML(XMLPlatformUtilsException,
  327.                  XMLExcepts::File_CouldNotSeekToEnd);
  328.     // And put the pointer back
  329.     if (fseek( (FILE*)theFile, curPos, SEEK_SET) )
  330.         ThrowXML(XMLPlatformUtilsException,
  331.                  XMLExcepts::File_CouldNotSeekToPos);
  332.     return (unsigned int)retVal;
  333. }
  334. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  335. {
  336.     const char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  337.     ArrayJanitor<char> janText((char*)tmpFileName, fgMemoryManager);
  338.     FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" );
  339.     if (retVal == NULL)
  340.         return 0;
  341.     return retVal;
  342. }
  343. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  344. {
  345.     FileHandle retVal = (FILE*)fopen( fileName , "rb" );
  346.     if (retVal == NULL)
  347.         return 0;
  348.     return retVal;
  349. }
  350. FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  351. {
  352.     const char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  353.     ArrayJanitor<char> janText((char*)tmpFileName, fgMemoryManager);
  354.     return fopen( tmpFileName , "wb" );
  355. }
  356. FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  357. {
  358.     return fopen( fileName , "wb" );
  359. }
  360. FileHandle XMLPlatformUtils::openStdInHandle()
  361. {
  362.     return (FileHandle)fdopen(dup(0), "rb");
  363. }
  364. unsigned int
  365. XMLPlatformUtils::readFileBuffer( FileHandle          theFile
  366.                                 , const unsigned int  toRead
  367.                                 , XMLByte* const      toFill)
  368. {
  369.     size_t noOfItemsRead = fread((void*) toFill, 1, toRead, (FILE*)theFile);
  370.     if(ferror((FILE*)theFile))
  371.     {
  372.         ThrowXML(XMLPlatformUtilsException,
  373.                  XMLExcepts::File_CouldNotReadFromFile);
  374.     }
  375.     return (unsigned int)noOfItemsRead;
  376. }
  377. void
  378. XMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile
  379.                                    , long                  toWrite
  380.                                    , const XMLByte* const  toFlush)
  381. {
  382.     if (!theFile        ||
  383.         (toWrite <= 0 ) ||
  384.         !toFlush         )
  385.         return;
  386.     const XMLByte* tmpFlush = (const XMLByte*) toFlush;
  387.     size_t bytesWritten = 0;
  388.     while (true)
  389.     {
  390.         bytesWritten=fwrite(tmpFlush, sizeof(XMLByte), toWrite, (FILE*)theFile);
  391.         if(ferror((FILE*)theFile))
  392.         {
  393.             ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  394.         }
  395.         if (bytesWritten < toWrite) //incomplete write
  396.         {
  397.             tmpFlush+=bytesWritten;
  398.             toWrite-=bytesWritten;
  399.             bytesWritten=0;
  400.         }
  401.         else
  402.             return;
  403.     }
  404.     return;
  405. }
  406. void XMLPlatformUtils::resetFile(FileHandle theFile)
  407. {
  408.     // Seek to the start of the file
  409.     if (fseek((FILE*)theFile, 0, SEEK_SET))
  410.         ThrowXML(XMLPlatformUtilsException,
  411.                  XMLExcepts::File_CouldNotResetFile);
  412. }
  413. // ---------------------------------------------------------------------------
  414. //  XMLPlatformUtils: File system methods
  415. // ---------------------------------------------------------------------------
  416. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath,
  417.                                      MemoryManager* const manager)
  418. {
  419.     //
  420.     //  NOTE: THe path provided has always already been opened successfully,
  421.     //  so we know that its not some pathological freaky path. It comes in
  422.     //  in native format, and goes out as Unicode always
  423.     //
  424.     char* newSrc = XMLString::transcode(srcPath, fgMemoryManager);
  425.     ArrayJanitor<char> janText(newSrc, fgMemoryManager);
  426.     // Use a local buffer that is big enough for the largest legal path
  427.     char absPath[PATH_MAX + 1];
  428.     // get the absolute path
  429.     char* retPath = realpath(newSrc, &absPath[0]);
  430.     if (!retPath)
  431.     {
  432.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  433.     }
  434.     return XMLString::transcode(absPath, manager);
  435. }
  436. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  437. {
  438.     // Check for pathological case of empty path
  439.     if (!toCheck[0])
  440.         return false;
  441.     //
  442.     //  If it starts with a slash, then it cannot be relative. This covers
  443.     //  both something like "TestFile.xml" and an NT Lan type remote path
  444.     //  that starts with a node like "\MyNodeTestFile.xml".
  445.     //
  446.     if (toCheck[0] == XMLCh('/'))
  447.         return false;
  448.     // Else assume its a relative path
  449.     return true;
  450. }
  451. XMLCh* XMLPlatformUtils::getCurrentDirectory(MemoryManager* const manager)
  452. {
  453.     char  dirBuf[PATH_MAX + 1];
  454.     char  *curDir = getcwd(&dirBuf[0], PATH_MAX + 1);
  455.     if (!curDir)
  456.     {
  457.         ThrowXML(XMLPlatformUtilsException,
  458.                  XMLExcepts::File_CouldNotGetBasePathName);
  459.     }
  460.     return XMLString::transcode(curDir, manager);
  461. }
  462. inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
  463. {
  464.     return ( chBackSlash == c || chForwardSlash == c);
  465. }
  466. // ---------------------------------------------------------------------------
  467. //  XMLPlatformUtils: Timing Methods
  468. // ---------------------------------------------------------------------------
  469. unsigned long XMLPlatformUtils::getCurrentMillis()
  470. {
  471.     timeb aTime;
  472.     ftime(&aTime);
  473.     return (unsigned long)(aTime.time*1000 + aTime.millitm);
  474. }
  475. // -----------------------------------------------------------------------
  476. //  Mutex methods
  477. // -----------------------------------------------------------------------
  478. #if !defined(APP_NO_THREADS)
  479. // ---------------------------------------------------------------------------
  480. //  XMLPlatformUtils: Platform init method
  481. // ---------------------------------------------------------------------------
  482. static XMLMutex atomicOpsMutex;
  483. void XMLPlatformUtils::platformInit()
  484. {
  485.     //
  486.     // The atomicOps mutex needs to be created early.
  487.     // Normally, mutexes are created on first use, but there is a
  488.     // circular dependency between compareAndExchange() and
  489.     // mutex creation that must be broken.
  490.     if (atomicOpsMutex.fHandle == 0)
  491.         atomicOpsMutex.fHandle = XMLPlatformUtils::makeMutex();
  492. }
  493. void* XMLPlatformUtils::makeMutex()
  494. {
  495.     pthread_mutex_t* mutex = new pthread_mutex_t;
  496.     pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  497.     pthread_mutexattr_init(attr);
  498.     pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE_NP);
  499.     if (pthread_mutex_init(mutex, attr))
  500.     {
  501.         ThrowXML(XMLPlatformUtilsException,
  502.                  XMLExcepts::Mutex_CouldNotCreate);
  503.     }
  504.     pthread_mutexattr_destroy(attr);
  505.     delete attr;
  506.     return (void*)(mutex);
  507. }
  508. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  509. {
  510.     if (mtxHandle != NULL)
  511.     {
  512.         if (pthread_mutex_destroy((pthread_mutex_t*) mtxHandle))
  513.         {
  514.             ThrowXML(XMLPlatformUtilsException,
  515.                      XMLExcepts::Mutex_CouldNotDestroy);
  516.         }
  517.         delete (pthread_mutex_t*) mtxHandle;
  518.     }
  519. }
  520. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  521. {
  522.     if (mtxHandle != NULL)
  523.     {
  524.         if (pthread_mutex_lock((pthread_mutex_t*) mtxHandle))
  525.         {
  526.             ThrowXML(XMLPlatformUtilsException,
  527.                      XMLExcepts::Mutex_CouldNotLock);
  528.         }
  529.     }
  530. }
  531. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  532. {
  533.     if (mtxHandle != NULL)
  534.     {
  535.         if (pthread_mutex_unlock((pthread_mutex_t*) mtxHandle))
  536.         {
  537.             ThrowXML(XMLPlatformUtilsException,
  538.                      XMLExcepts::Mutex_CouldNotUnlock);
  539.         }
  540.     }
  541. }
  542. // -----------------------------------------------------------------------
  543. //  Miscellaneous synchronization methods
  544. // -----------------------------------------------------------------------
  545. void* XMLPlatformUtils::compareAndSwap(void**            toFill
  546.                                      , const void* const newValue
  547.                                      , const void* const toCompare)
  548. {
  549.     XMLMutexLock lockMutex(&atomicOpsMutex);
  550.     void *retVal = *toFill;
  551.     if (*toFill == toCompare)
  552.         *toFill = (void *)newValue;
  553.     return retVal;
  554. }
  555. int XMLPlatformUtils::atomicIncrement(int &location)
  556. {
  557.     XMLMutexLock localLock(&atomicOpsMutex);
  558.     return ++location;
  559. }
  560. int XMLPlatformUtils::atomicDecrement(int &location)
  561. {
  562.     XMLMutexLock localLock(&atomicOpsMutex);
  563.     return --location;
  564. }
  565. #else // #if !defined (APP_NO_THREADS)
  566. void XMLPlatformUtils::platformInit()
  567. {
  568. }
  569. void* XMLPlatformUtils::makeMutex()
  570. {
  571.         return 0;
  572. }
  573. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  574. {
  575. }
  576. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  577. {
  578. }
  579. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  580. {
  581. }
  582. void* XMLPlatformUtils::compareAndSwap (void**             toFill,
  583.                                         const void* const  newValue,
  584.                                         const void* const  toCompare)
  585. {
  586.     void *retVal = *toFill;
  587.     if (*toFill == toCompare)
  588.        *toFill = (void *)newValue;
  589.     return retVal;
  590. }
  591. int XMLPlatformUtils::atomicIncrement(int &location)
  592. {
  593.     return ++location;
  594. }
  595. int XMLPlatformUtils::atomicDecrement(int &location)
  596. {
  597.     return --location;
  598. }
  599. #endif // APP_NO_THREADS
  600. void XMLPlatformUtils::platformTerm()
  601. {
  602. #if !defined(APP_NO_THREADS)
  603.     // delete the mutex we created
  604. closeMutex(atomicOpsMutex.fHandle);
  605. atomicOpsMutex.fHandle = 0;
  606. #endif
  607. }
  608. #include <xercesc/util/LogicalPath.c>
  609. XERCES_CPP_NAMESPACE_END