Home | History | Annotate | Download | only in source
      1 /*****************************************************************************/
      2 // Copyright 2006 Adobe Systems Incorporated
      3 // All Rights Reserved.
      4 //
      5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
      6 // accordance with the terms of the Adobe license agreement accompanying it.
      7 /*****************************************************************************/
      8 
      9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_ref_counted_block.cpp#1 $ */
     10 /* $DateTime: 2012/05/30 13:28:51 $ */
     11 /* $Change: 832332 $ */
     12 /* $Author: tknoll $ */
     13 
     14 /*****************************************************************************/
     15 
     16 #include <new>
     17 
     18 #include "dng_ref_counted_block.h"
     19 
     20 #include "dng_exceptions.h"
     21 
     22 /*****************************************************************************/
     23 
     24 dng_ref_counted_block::dng_ref_counted_block ()
     25 
     26 	:	fBuffer (NULL)
     27 
     28 	{
     29 
     30 	}
     31 
     32 /*****************************************************************************/
     33 
     34 dng_ref_counted_block::dng_ref_counted_block (uint32 size)
     35 
     36 	:	fBuffer (NULL)
     37 
     38 	{
     39 
     40 	Allocate (size);
     41 
     42 	}
     43 
     44 /*****************************************************************************/
     45 
     46 dng_ref_counted_block::~dng_ref_counted_block ()
     47 	{
     48 
     49 	Clear ();
     50 
     51 	}
     52 
     53 /*****************************************************************************/
     54 
     55 void dng_ref_counted_block::Allocate (uint32 size)
     56 	{
     57 
     58 	Clear ();
     59 
     60 	if (size)
     61 		{
     62 
     63 		fBuffer = malloc (size + sizeof (header));
     64 
     65 		if (!fBuffer)
     66 			{
     67 
     68 			ThrowMemoryFull ();
     69 
     70 			}
     71 
     72 		new (fBuffer) header (size);
     73 
     74 		}
     75 
     76 	}
     77 
     78 /*****************************************************************************/
     79 
     80 void dng_ref_counted_block::Clear ()
     81 	{
     82 
     83 	if (fBuffer)
     84 		{
     85 
     86 
     87 		bool doFree = false;
     88 
     89 		header *blockHeader = (struct header *)fBuffer;
     90 
     91 			{
     92 
     93 			dng_lock_mutex lock (&blockHeader->fMutex);
     94 
     95 			if (--blockHeader->fRefCount == 0)
     96 				doFree = true;
     97 			}
     98 
     99 		if (doFree)
    100 			{
    101 
    102 			blockHeader->~header ();
    103 
    104 			free (fBuffer);
    105 
    106 			}
    107 
    108 		fBuffer = NULL;
    109 
    110 		}
    111 
    112 	}
    113 
    114 /*****************************************************************************/
    115 
    116 dng_ref_counted_block::dng_ref_counted_block (const dng_ref_counted_block &data)
    117 	: fBuffer (NULL)
    118 	{
    119 
    120 	header *blockHeader = (struct header *)data.fBuffer;
    121 
    122 	dng_lock_mutex lock (&blockHeader->fMutex);
    123 
    124 	blockHeader->fRefCount++;
    125 
    126 	fBuffer = blockHeader;
    127 
    128 	}
    129 
    130 /*****************************************************************************/
    131 
    132 dng_ref_counted_block & dng_ref_counted_block::operator= (const dng_ref_counted_block &data)
    133 	{
    134 
    135 	if (this != &data)
    136 		{
    137 		Clear ();
    138 
    139 		header *blockHeader = (struct header *)data.fBuffer;
    140 
    141 		dng_lock_mutex lock (&blockHeader->fMutex);
    142 
    143 		blockHeader->fRefCount++;
    144 
    145 		fBuffer = blockHeader;
    146 
    147 		}
    148 
    149 	return *this;
    150 
    151 	}
    152 
    153 /*****************************************************************************/
    154 
    155 void dng_ref_counted_block::EnsureWriteable ()
    156 	{
    157 
    158 	if (fBuffer)
    159 		{
    160 
    161 		header *possiblySharedHeader = (header *)fBuffer;
    162 
    163 			{
    164 
    165 			dng_lock_mutex lock (&possiblySharedHeader->fMutex);
    166 
    167 			if (possiblySharedHeader->fRefCount > 1)
    168 				{
    169 
    170 				fBuffer = NULL;
    171 
    172 				Allocate ((uint32)possiblySharedHeader->fSize);
    173 
    174 				memcpy (Buffer (),
    175 					((char *)possiblySharedHeader) + sizeof (struct header), // could just do + 1 w/o cast, but this makes the type mixing more explicit
    176 					possiblySharedHeader->fSize);
    177 
    178 				possiblySharedHeader->fRefCount--;
    179 
    180 				}
    181 
    182 			}
    183 
    184 		}
    185 	}
    186 
    187 /*****************************************************************************/
    188