SBtrdRefCount.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:4k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /* SBtrdRefCount, class for managing reference counts */
  2. /****************License************************************************
  3.  * Vocalocity OpenVXI
  4.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *  
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  19.  * registered trademarks of Vocalocity, Inc. 
  20.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  21.  * by Vocalocity.
  22.  ***********************************************************************/
  23. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  24. #include <limits.h>                        // For ULONG_MAX
  25. #define SBTRDUTIL_EXPORTS
  26. #include "SBtrdMutex.hpp"                  // For the GlobalMutex class
  27. #include "SBtrdRefCount.hpp"               // For this class
  28. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  29. // Add a reference to an object
  30. SBTRDUTIL_API_CLASS VXItrdResult 
  31. SBtrdRefCount::AddRef (SBtrdRefCount *obj)
  32. {
  33.   if ( obj == NULL ) return VXItrd_RESULT_INVALID_ARGUMENT;
  34.   // Do optional mutex locking
  35.   VXItrdResult rc = VXItrd_RESULT_SUCCESS;
  36.   if (( obj->_mutex ) && 
  37.       ((rc = obj->_mutex->Lock( )) != VXItrd_RESULT_SUCCESS ))
  38.     return rc;
  39.   // Increment the reference count
  40.   if ( obj->_refCount < ULONG_MAX )
  41.     (obj->_refCount)++;
  42.   else
  43.     rc = VXItrd_RESULT_FATAL_ERROR;
  44.   // Release the mutex lock
  45.   if ( obj->_mutex ) {
  46.     VXItrdResult rc2 =  obj->_mutex->Unlock( );
  47.     if (rc2 != VXItrd_RESULT_SUCCESS )
  48.       rc = rc2;
  49.   }
  50.   return rc;
  51. }
  52. // Release a reference. Note: this sets the passed pointer to NULL.
  53. SBTRDUTIL_API_CLASS VXItrdResult 
  54. SBtrdRefCount::Release (SBtrdRefCount **obj)
  55. {
  56.   if (( ! obj ) || ( ! *obj )) return VXItrd_RESULT_INVALID_ARGUMENT;
  57.   // Do optional mutex locking
  58.   VXItrdResult rc = VXItrd_RESULT_SUCCESS;
  59.   if (( (*obj)->_mutex ) && 
  60.       ((rc = (*obj)->_mutex->Lock( )) != VXItrd_RESULT_SUCCESS ))
  61.     return rc;
  62.   // Decrement the reference count
  63.   unsigned long count = 999;
  64.   if ( (*obj)->_refCount > 0 )
  65.     count = --((*obj)->_refCount);
  66.   else
  67.     rc = VXItrd_RESULT_FATAL_ERROR;
  68.   // Release the mutex lock
  69.   if ( (*obj)->_mutex ) {
  70.     VXItrdResult rc2 =  (*obj)->_mutex->Unlock( );
  71.     if (rc2 != VXItrd_RESULT_SUCCESS )
  72.       rc = rc2;
  73.   }
  74.   // Invalidate the pointer and return
  75.   if ( count == 0 )
  76.     delete *obj;
  77.   *obj = NULL;
  78.   return rc;
  79. }
  80. // Get a unique copy if this is being shared in preparation for a
  81. // write operation, don't want to change this under someone else's
  82. // feet. The passed pointer will be changed if this is being shared.
  83. SBTRDUTIL_API_CLASS VXItrdResult 
  84. SBtrdRefCount::GetUniqueCopy (SBtrdRefCount **obj,
  85.       SBtrdMutex *mutex)
  86. {
  87.   if (( ! obj ) || ( ! *obj )) return VXItrd_RESULT_INVALID_ARGUMENT;
  88.   // Do optional mutex locking
  89.   VXItrdResult rc = VXItrd_RESULT_SUCCESS;
  90.   if (( (*obj)->_mutex ) && 
  91.       ((rc = (*obj)->_mutex->Lock( )) != VXItrd_RESULT_SUCCESS ))
  92.     return rc;
  93.   // Do the split if the ref count is greater then 1
  94.   SBtrdRefCount *newObj = NULL;
  95.   if ( (*obj)->_refCount > 1 ) {
  96.     if ( (newObj = (*obj)->AllocateCopy( )) != NULL ) {
  97.       (*obj)->_refCount--;
  98.       if ( mutex )
  99. newObj->_mutex = mutex;
  100.     } else {
  101.       rc = VXItrd_RESULT_OUT_OF_MEMORY;
  102.     }
  103.   }
  104.   // Release the mutex lock
  105.   if ( (*obj)->_mutex ) {
  106.     VXItrdResult rc2 =  (*obj)->_mutex->Unlock( );
  107.     if (rc2 != VXItrd_RESULT_SUCCESS )
  108.       rc = rc2;
  109.   }
  110.   
  111.   // Return the pointer now that we've unlocked the mutex
  112.   if ( newObj != NULL )
  113.     *obj = newObj;
  114.   return rc;
  115. }