HPPlatformUtils.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:22k
源码类别:

xml/soap/webservice

开发平台:

C/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: HPPlatformUtils.cpp,v $
  58.  * Revision 1.17  2001/10/25 15:20:31  tng
  59.  * Need to guard with NO_APP_THREADS when destroying the mutex.
  60.  *
  61.  * Revision 1.16  2001/10/23 23:10:00  peiyongz
  62.  * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  63.  *
  64.  * Revision 1.15  2000/09/22 18:31:41  andyh
  65.  * HPUX PlatformUtils - Removed incorrect use of ArrayJanitor on a local array.
  66.  * Patch submitted by "Torbj鰎n B鋍kstr鰉" <torbjorn.backstrom@teleteknik.goteborg.se>
  67.  *
  68.  * Revision 1.14  2000/07/25 22:29:36  aruna1
  69.  * Char definitions in XMLUni moved to XMLUniDefs
  70.  *
  71.  * Revision 1.13  2000/03/24 00:16:00  aruna1
  72.  * Platform initialization taken care for both threaded and non-threaded environment
  73.  *
  74.  * Revision 1.12  2000/03/20 23:48:51  rahulj
  75.  * Added Socket based NetAccessor. This will enable one to
  76.  * use HTTP URL's for system id's. Default build options do
  77.  * not use this NetAccessor. Specify the '-n socket' option
  78.  * to 'runConfigure' to configure Xerces-C to use this new
  79.  * feature. The code works under Solaris 2.6, Linux, AIX
  80.  * and HPUX 11 with aCC.
  81.  * Todo's: enable proper error handling.
  82.  *
  83.  * Revision 1.11  2000/03/17 23:59:59  roddey
  84.  * Initial updates for two way transcoding support
  85.  *
  86.  * Revision 1.10  2000/03/02 21:10:35  abagchi
  87.  * Added empty function platformTerm()
  88.  *
  89.  * Revision 1.9  2000/03/02 20:42:40  abagchi
  90.  * Fixed typo in XMLExcepts
  91.  *
  92.  * Revision 1.8  2000/03/02 19:55:21  roddey
  93.  * This checkin includes many changes done while waiting for the
  94.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  95.  * available elsewhere.
  96.  *
  97.  * Revision 1.7  2000/02/06 07:48:26  rahulj
  98.  * Year 2K copyright swat.
  99.  *
  100.  * Revision 1.6  2000/01/25 22:32:45  aruna1
  101.  * Updated panic information
  102.  *
  103.  * Revision 1.5  2000/01/20 20:37:55  abagchi
  104.  * Removed fgLibLocation and cleaned up ICU path related stuff
  105.  *
  106.  * Revision 1.4  2000/01/18 21:33:17  aruna1
  107.  * Changed getBasePath to getFullPath,
  108.  * added weavePath()
  109.  *
  110.  * Revision 1.3  1999/12/14 23:53:31  rahulj
  111.  * Removed the offending Ctrl-M's from the commit message
  112.  * logs which was giving packaging problems.
  113.  *
  114.  * PR:
  115.  * Obtained from:
  116.  * Submitted by:
  117.  * Reviewed by:
  118.  *
  119.  * Revision 1.2  1999/11/23 02:00:44  rahulj
  120.  * Code now works under HPUX 11. Tested inmemory message loader.
  121.  * Revamped makefiles. Builds with both DCE threads as well as pthread libraries.
  122.  *
  123.  * Revision 1.1.1.1  1999/11/09 01:07:05  twl
  124.  * Initial checkin
  125.  *
  126.  * Revision 1.3  1999/11/08 20:45:29  rahul
  127.  * Swat for adding in Product name and CVS comment log variable.
  128.  *
  129.  */
  130. // ---------------------------------------------------------------------------
  131. //  Includes
  132. // ---------------------------------------------------------------------------
  133. #if !defined(APP_NO_THREADS)
  134. #include    <pthread.h>
  135. #endif // APP_NO_THREADS
  136. #include    <util/PlatformUtils.hpp>
  137. #include    <util/RuntimeException.hpp>
  138. #include    <util/Janitor.hpp>
  139. #include    <util/Mutexes.hpp>
  140. #include    <dl.h>
  141. #include    <stdio.h>
  142. #include    <stdlib.h>
  143. #include    <errno.h>
  144. #include    <libgen.h>
  145. #include    <string.h>
  146. #include    <limits.h>
  147. #include    <unistd.h>
  148. #include    <util/XMLString.hpp>
  149. #include    <util/XMLUniDefs.hpp>
  150. #include    <util/XMLUni.hpp>
  151. #if defined(XML_USE_ICU_TRANSCODER)
  152.     #include <util/Transcoders/ICU/ICUTransService.hpp>
  153. #else
  154.     // Use native transcoder. Same as -DXML_USE_NATIVE_TRANSCODER
  155.     #include <util/Transcoders/Iconv/IconvTransService.hpp>
  156. #endif
  157. #if defined(XML_USE_ICU_MESSAGELOADER)
  158.     #include <util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  159. #else
  160.     // Same as -DXML_USE_INMEM_MESSAGELOADER
  161.     #include <util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  162. #endif
  163. #if defined (XML_USE_NETACCESSOR_SOCKET)
  164.     #include <util/NetAccessors/Socket/SocketNetAccessor.hpp>
  165. #endif
  166. #if !defined(XML_HPUX_KAICC)
  167. #include    <sys/timeb.h>             // does not work with KAI compiler
  168. #endif
  169. // ---------------------------------------------------------------------------
  170. //  Local Methods
  171. // ---------------------------------------------------------------------------
  172. static void WriteCharStr(FILE* stream, const char* const toWrite)
  173. {
  174.     if (fputs(toWrite, stream) == EOF)
  175.     {
  176.         ThrowXML(XMLPlatformUtilsException,
  177.                  XMLExcepts::Strm_StdErrWriteFailure);
  178.     }
  179. }
  180. static void WriteUStrStdErr(const XMLCh* const toWrite)
  181. {
  182.     char* tmpVal = XMLString::transcode(toWrite);
  183.     ArrayJanitor<char> janText(tmpVal);
  184.     if (fputs(tmpVal, stderr) == EOF)
  185.     {
  186.         ThrowXML(XMLPlatformUtilsException,
  187.                  XMLExcepts::Strm_StdErrWriteFailure);
  188.     }
  189. }
  190. static void WriteUStrStdOut(const XMLCh* const toWrite)
  191. {
  192.     char* tmpVal = XMLString::transcode(toWrite);
  193.     ArrayJanitor<char> janText(tmpVal);
  194.     if (fputs(tmpVal, stdout) == EOF)
  195.     {
  196.         ThrowXML(XMLPlatformUtilsException,
  197.                  XMLExcepts::Strm_StdOutWriteFailure);
  198.     }
  199. }
  200. //
  201. //  This method is called by the platform independent part of this class
  202. //  during initialization. We have to create the type of net accessor that
  203. //  we want to use.
  204. //
  205. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  206. {
  207. #if defined (XML_USE_NETACCESSOR_SOCKET)
  208.     return new SocketNetAccessor();
  209. #else
  210.     return 0;
  211. #endif
  212. }
  213. // ---------------------------------------------------------------------------
  214. //  XMLPlatformUtils: Private Static Methods
  215. // ---------------------------------------------------------------------------
  216. //
  217. //  This method is called by the platform independent part of this class
  218. //  when client code asks to have one of the supported message sets loaded.
  219. //  In our case, we use the ICU based message loader mechanism.
  220. //
  221. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  222. {
  223.     XMLMsgLoader* retVal;
  224.     try
  225.     {
  226. #if defined (XML_USE_ICU_MESSAGELOADER)
  227.         retVal = new ICUMsgLoader(msgDomain);
  228. #else
  229.         // same as -DXML_USE_INMEM_MESSAGELOADER
  230.         retVal = new InMemMsgLoader(msgDomain);
  231. #endif
  232.     }
  233.     catch(...)
  234.     {
  235.         panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
  236.     }
  237.     return retVal;
  238. }
  239. //
  240. //  This method is called very early in the bootstrapping process. This guy
  241. //  must create a transcoding service and return it. It cannot use any string
  242. //  methods, any transcoding services, throw any exceptions, etc... It just
  243. //  makes a transcoding service and returns it, or returns zero on failure.
  244. //
  245. XMLTransService* XMLPlatformUtils::makeTransService()
  246. {
  247. #if defined (XML_USE_ICU_TRANSCODER)
  248.     return new ICUTransService;
  249. #else
  250.     // Use native transcoding services.
  251.     // same as -DXML_USE_INMEM_MESSAGELOADER
  252.     return new IconvTransService;
  253. #endif
  254. } // XMLPlatformUtils::makeTransService
  255. // ---------------------------------------------------------------------------
  256. //  XMLPlatformUtils: The panic method
  257. // ---------------------------------------------------------------------------
  258. void XMLPlatformUtils::panic(const PanicReasons reason)
  259. {
  260.      const char* reasonStr = "Unknown reason";
  261.     if (reason == Panic_NoTransService)
  262.         reasonStr = "Could not load a transcoding service";
  263.     else if (reason == Panic_NoDefTranscoder)
  264.         reasonStr = "Could not load a local code page transcoder";
  265.     else if (reason == Panic_CantFindLib)
  266.         reasonStr = "Could not find the xerces-c DLL";
  267.     else if (reason == Panic_UnknownMsgDomain)
  268.         reasonStr = "Unknown message domain";
  269.     else if (reason == Panic_CantLoadMsgDomain)
  270.         reasonStr = "Cannot load message domain";
  271.     else if (reason == Panic_SynchronizationErr)
  272.         reasonStr = "Cannot synchronize system or mutex";
  273.     else if (reason == Panic_SystemInit)
  274.         reasonStr = "Cannot initialize the system or mutex";
  275.     fprintf(stderr, "%sn", reasonStr);
  276.     exit(-1);
  277. }
  278. // ---------------------------------------------------------------------------
  279. //  XMLPlatformUtils: File Methods
  280. // ---------------------------------------------------------------------------
  281. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  282. {
  283.     // Get the current position
  284.     long  curPos = ftell((FILE*) theFile);
  285.     if (curPos == -1)
  286.         ThrowXML(XMLPlatformUtilsException,
  287.                  XMLExcepts::File_CouldNotGetCurPos);
  288.     return (unsigned int) curPos;
  289. }
  290. void XMLPlatformUtils::closeFile(FileHandle theFile)
  291. {
  292.     if (fclose((FILE*) theFile))
  293.         ThrowXML(XMLPlatformUtilsException,
  294.                  XMLExcepts::File_CouldNotCloseFile);
  295. }
  296. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  297. {
  298.     // Get the current position
  299.     long  int curPos = ftell((FILE*) theFile);
  300.     if (curPos == -1)
  301.     {
  302.         ThrowXML(XMLPlatformUtilsException,
  303.                  XMLExcepts::File_CouldNotGetCurPos);
  304.     }
  305.     // Seek to the end and save that value for return
  306.      if (fseek((FILE*) theFile, 0, SEEK_END))
  307.      {
  308.         ThrowXML(XMLPlatformUtilsException,
  309.                  XMLExcepts::File_CouldNotSeekToEnd);
  310.      }
  311.     long int retVal = ftell((FILE*) theFile);
  312.     if (retVal == -1)
  313.         ThrowXML(XMLPlatformUtilsException,
  314.                  XMLExcepts::File_CouldNotGetSize);
  315.     // And put the pointer back
  316.     if (fseek((FILE*) theFile, curPos, SEEK_SET))
  317.         ThrowXML(XMLPlatformUtilsException,
  318.                  XMLExcepts::File_CouldNotSeekToPos);
  319.     return (unsigned int) retVal;
  320. }
  321. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  322. {
  323.     FileHandle retVal = (FILE*) fopen(fileName , "rb");
  324.     return retVal;
  325. }
  326. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  327. {
  328.     char* tmpFileName = XMLString::transcode(fileName);
  329.     FileHandle retVal = (FILE*) fopen(tmpFileName , "rb");
  330.     delete [] tmpFileName;
  331.     return retVal;
  332. }
  333. FileHandle XMLPlatformUtils::openStdInHandle()
  334. {
  335.     return (FileHandle) fdopen(dup(0), "rb");
  336. }
  337. unsigned int
  338. XMLPlatformUtils::readFileBuffer(       FileHandle      theFile
  339.                                 , const unsigned int    toRead
  340.                                 ,       XMLByte* const  toFill)
  341. {
  342.     size_t noOfItemsRead = fread((void*) toFill, 1, toRead, (FILE*)theFile);
  343.     if (ferror((FILE*)theFile))
  344.     {
  345.         ThrowXML(XMLPlatformUtilsException,
  346.                  XMLExcepts::File_CouldNotReadFromFile);
  347.     }
  348.     return (unsigned int) noOfItemsRead;
  349. }
  350. void XMLPlatformUtils::resetFile(FileHandle theFile)
  351. {
  352.     // Seek to the start of the file
  353.     if (fseek((FILE*) theFile, 0, SEEK_SET))
  354.         ThrowXML(XMLPlatformUtilsException,
  355.                  XMLExcepts::File_CouldNotResetFile);
  356. }
  357. // ---------------------------------------------------------------------------
  358. //  XMLPlatformUtils: Timing Methods
  359. // ---------------------------------------------------------------------------
  360. unsigned long XMLPlatformUtils::getCurrentMillis()
  361. {
  362. #if defined(XML_HPUX_KAICC)         // should be reimplemented by someone with
  363.                                     // HP/UX and KAI knowledge.
  364.     return (unsigned long) 0;
  365. #else
  366.     timeb aTime;
  367.     ftime(&aTime);
  368.     return (unsigned long)(aTime.time*1000 + aTime.millitm);
  369. #endif
  370. }
  371. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
  372. {
  373.     //
  374.     //  NOTE: THe path provided has always already been opened successfully,
  375.     //  so we know that its not some pathological freaky path. It comes in
  376.     //  in native format, and goes out as Unicode always
  377.     //
  378.     char* newSrc = XMLString::transcode(srcPath);
  379.     ArrayJanitor<char> janText(newSrc);
  380.     // Use a local buffer that is big enough for the largest legal path
  381.     char absPath[PATH_MAX];
  382.     //get the absolute path
  383.     char* retPath = realpath(newSrc, &absPath[0]);
  384.     if (!retPath)
  385.     {
  386.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  387.     }
  388.     return XMLString::transcode(absPath);
  389. }
  390. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  391. {
  392.     // Check for pathological case of empty path
  393.     if (!toCheck[0])
  394.         return false;
  395.     //
  396.     //  If it starts with a slash, then it cannot be relative. This covers
  397.     //  both something like "TestFile.xml" and an NT Lan type remote path
  398.     //  that starts with a node like "\MyNodeTestFile.xml".
  399.     //
  400.     if (toCheck[0] == XMLCh('/'))
  401.         return false;
  402.     // Else assume its a relative path
  403.     return true;
  404. }
  405. XMLCh* XMLPlatformUtils::weavePaths
  406.     (
  407.         const   XMLCh* const    basePath
  408.         , const XMLCh* const    relativePath
  409.     )
  410. {
  411. // Create a buffer as large as both parts and empty it
  412.     XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
  413.                               + XMLString::stringLen(relativePath)
  414.                               + 2];
  415.     *tmpBuf = 0;
  416.     //
  417.     //  If we have no base path, then just take the relative path as
  418.     //  is.
  419.     //
  420.     if (!basePath)
  421.     {
  422.         XMLString::copyString(tmpBuf, relativePath);
  423.         return tmpBuf;
  424.     }
  425.     if (!*basePath)
  426.     {
  427.         XMLString::copyString(tmpBuf, relativePath);
  428.         return tmpBuf;
  429.     }
  430.     const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
  431.     if ((*basePtr != chForwardSlash)
  432.     &&  (*basePtr != chBackSlash))
  433.     {
  434.         while ((basePtr >= basePath)
  435.         &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  436.         {
  437.             basePtr--;
  438.         }
  439.     }
  440.     // There is no relevant base path, so just take the relative part
  441.     if (basePtr < basePath)
  442.     {
  443.         XMLString::copyString(tmpBuf, relativePath);
  444.         return tmpBuf;
  445.     }
  446.     // After this, make sure the buffer gets handled if we exit early
  447.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  448.     //
  449.     //  We have some path part, so we need to check to see if we ahve to
  450.     //  weave any of the parts together.
  451.     //
  452.     const XMLCh* pathPtr = relativePath;
  453.     while (true)
  454.     {
  455.         // If it does not start with some period, then we are done
  456.         if (*pathPtr != chPeriod)
  457.             break;
  458.         unsigned int periodCount = 1;
  459.         pathPtr++;
  460.         if (*pathPtr == chPeriod)
  461.         {
  462.             pathPtr++;
  463.             periodCount++;
  464.         }
  465.         // Has to be followed by a  or / or the null to mean anything
  466.         if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
  467.         &&  *pathPtr)
  468.         {
  469.             break;
  470.         }
  471.         if (*pathPtr)
  472.             pathPtr++;
  473.         // If its one period, just eat it, else move backwards in the base
  474.         if (periodCount == 2)
  475.         {
  476.             basePtr--;
  477.             while ((basePtr >= basePath)
  478.             &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  479.             {
  480.                 basePtr--;
  481.             }
  482.             // The base cannot provide enough levels, so its in error/
  483.             if (basePtr < basePath)
  484.                 ThrowXML(XMLPlatformUtilsException,
  485.                          XMLExcepts::File_BasePathUnderflow);
  486.         }
  487.     }
  488.     // Copy the base part up to the base pointer
  489.     XMLCh* bufPtr = tmpBuf;
  490.     const XMLCh* tmpPtr = basePath;
  491.     while (tmpPtr <= basePtr)
  492.         *bufPtr++ = *tmpPtr++;
  493.     // And then copy on the rest of our path
  494.     XMLString::copyString(bufPtr, pathPtr);
  495.     // Orphan the buffer and return it
  496.     janBuf.orphan();
  497.     return tmpBuf;
  498. }
  499. // -----------------------------------------------------------------------
  500. //  Mutex methods
  501. // -----------------------------------------------------------------------
  502. #if !defined(APP_NO_THREADS)
  503. // ---------------------------------------------------------------------------
  504. //  XMLPlatformUtils: Platform init method
  505. // ---------------------------------------------------------------------------
  506. static XMLMutex atomicOpsMutex;
  507. void XMLPlatformUtils::platformInit()
  508. {
  509.     //
  510.     // The atomicOps mutex needs to be created early.
  511.     // Normally, mutexes are created on first use, but there is a
  512.     // circular dependency between compareAndExchange() and
  513.     // mutex creation that must be broken.
  514.     atomicOpsMutex.fHandle = XMLPlatformUtils::makeMutex();
  515. }
  516. void* XMLPlatformUtils::makeMutex()
  517. {
  518.     pthread_mutex_t* mutex = new pthread_mutex_t;
  519.     pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  520. #if defined(XML_USE_DCE)
  521.     pthread_mutexattr_create(attr);
  522.     pthread_mutexattr_setkind_np(attr, MUTEX_RECURSIVE_NP);
  523.     if (pthread_mutex_init(mutex, *attr))
  524.     {
  525.         ThrowXML(XMLPlatformUtilsException,
  526.                  XMLExcepts::Mutex_CouldNotCreate);
  527.     }
  528.     pthread_mutexattr_delete(attr);
  529. #else
  530.     pthread_mutexattr_init(attr);
  531.     pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
  532.     if (pthread_mutex_init(mutex, attr))
  533.     {
  534.         ThrowXML(XMLPlatformUtilsException,
  535.                  XMLExcepts::Mutex_CouldNotCreate);
  536.     }
  537.     pthread_mutexattr_destroy(attr);
  538. #endif
  539.     delete attr;
  540.     return (void*) mutex;
  541. }
  542. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  543. {
  544.     pthread_mutex_t* mutex = (pthread_mutex_t *) mtxHandle;
  545.     if (mutex != NULL)
  546.     {
  547.         if (pthread_mutex_destroy(mutex))
  548.             ThrowXML(XMLPlatformUtilsException,
  549.                   XMLExcepts::Mutex_CouldNotDestroy);
  550.         delete mutex;
  551.     }
  552. }
  553. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  554. {
  555.     if (mtxHandle != NULL)
  556.     {
  557.         if (pthread_mutex_lock((pthread_mutex_t *) mtxHandle))
  558.         {
  559.             ThrowXML(XMLPlatformUtilsException,
  560.                      XMLExcepts::Mutex_CouldNotLock);
  561.         }
  562.     }
  563. }
  564. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  565. {
  566.     if (mtxHandle != NULL)
  567.     {
  568.         if (pthread_mutex_unlock((pthread_mutex_t *) mtxHandle))
  569.         {
  570.             ThrowXML(XMLPlatformUtilsException,
  571.                      XMLExcepts::Mutex_CouldNotUnlock);
  572.         }
  573.     }
  574. }
  575. // -----------------------------------------------------------------------
  576. //  Miscellaneous synchronization methods
  577. // -----------------------------------------------------------------------
  578. void* XMLPlatformUtils::compareAndSwap ( void**      toFill,
  579.                                    const void* const newValue,
  580.                                    const void* const toCompare)
  581. {
  582.     XMLMutexLock  localLock(&atomicOpsMutex);
  583.     void *retVal = *toFill;
  584.     if (*toFill == toCompare)
  585.     {
  586.        *toFill = (void *)newValue;
  587.     }
  588.     return retVal;
  589. }
  590. int XMLPlatformUtils::atomicIncrement(int &location)
  591. {
  592.     XMLMutexLock localLock(&atomicOpsMutex);
  593.     return ++location;
  594. }
  595. int XMLPlatformUtils::atomicDecrement(int &location)
  596. {
  597.     XMLMutexLock localLock(&atomicOpsMutex);
  598.     return --location;
  599. }
  600. #else // #if !defined (APP_NO_THREADS)
  601. void XMLPlatformUtils::platformInit()
  602. {
  603. }
  604. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  605. {
  606. }
  607. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  608. {
  609. }
  610. void* XMLPlatformUtils::makeMutex()
  611. {
  612.     return 0;
  613. }
  614. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  615. {
  616. }
  617. void* XMLPlatformUtils::compareAndSwap (void**             toFill,
  618.                                         const void* const  newValue,
  619.                                         const void* const  toCompare)
  620. {
  621.     void *retVal = *toFill;
  622.     if (*toFill == toCompare)
  623.        *toFill = (void *)newValue;
  624.     return retVal;
  625. }
  626. int XMLPlatformUtils::atomicIncrement(int &location)
  627. {
  628.     return ++location;
  629. }
  630. int XMLPlatformUtils::atomicDecrement(int &location)
  631. {
  632.     return --location;
  633. }
  634. #endif // APP_NO_THREADS
  635. void XMLPlatformUtils::platformTerm()
  636. {
  637. #if !defined(APP_NO_THREADS)
  638.     // delete the mutex we created
  639. closeMutex(atomicOpsMutex.fHandle);
  640. atomicOpsMutex.fHandle = 0;
  641. #endif
  642. }