XnStatus XnServerSensorInvoker::OnStreamRemoved(const XnChar* StreamName)
{
	XnStatus nRetVal = XN_STATUS_OK;

	// no need to unregister from its props - they do not exist anymore.

	// remove stream data
	SensorInvokerStream* pServerStream = NULL;
	nRetVal = m_streams.Get(StreamName, pServerStream);
	XN_IS_STATUS_OK(nRetVal);

	nRetVal = m_sensor.DestroyStreamData(&pServerStream->pStreamData);
	XN_IS_STATUS_OK(nRetVal);

	XN_DELETE(pServerStream->pNewDataEvent);

	if (pServerStream->pSharedMemoryName != NULL)
	{
		XN_DELETE(pServerStream->pSharedMemoryName);
	}

	// destroy shared memory
	xnOSCloseSharedMemory(pServerStream->hSharedMemory);

	nRetVal = m_streams.Remove(StreamName);
	XN_IS_STATUS_OK(nRetVal);

	return (XN_STATUS_OK);
}
XnStatus XnSensorAudioStream::Free()
{
	m_Helper.Free();
	XnAudioStream::Free();
	if (m_hSharedMemory != NULL)
	{
		xnOSCloseSharedMemory(m_hSharedMemory);
		m_hSharedMemory = NULL;
	}
	return (XN_STATUS_OK);
}
XnStatus XnSharedMemoryBufferPool::AllocateBuffers()
{
	XnStatus nRetVal = XN_STATUS_OK;
	
	if (m_nBufferSize > m_nMaxBufferSize)
	{
		return XN_STATUS_ALLOC_FAILED;
	}

	if (m_pSharedMemoryAddress != NULL)
	{
		// already allocated. nothing to do here
		return (XN_STATUS_OK);
	}

	// first time. allocate shared memory
	XnUInt32 nTotalSize = m_nMaxBufferSize * m_nBufferCount;
	nRetVal = xnOSCreateSharedMemory(m_strName, nTotalSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, &m_hSharedMemory);
	XN_IS_STATUS_OK(nRetVal);

	void* pAddress;
	nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, &pAddress);
	if (nRetVal != XN_STATUS_OK)
	{
		xnOSCloseSharedMemory(m_hSharedMemory);
		m_hSharedMemory = NULL;
		return (nRetVal);
	}

	m_pSharedMemoryAddress = (XnUChar*)pAddress;

	// now allocate buffers
	for (XnUInt32 i = 0; i < m_nBufferCount; ++i)
	{
		XnBufferInPool* pBuffer = XN_NEW(XnBufferInPool);
		if (pBuffer == NULL)
		{
			Free();
			return (XN_STATUS_ALLOC_FAILED);
		}

		pBuffer->m_nID = i;

		pBuffer->SetExternalBuffer(m_pSharedMemoryAddress + i*m_nMaxBufferSize, m_nMaxBufferSize);

		xnDumpWriteString(Dump(), "Allocated buffer %u with size %u\n", i, m_nMaxBufferSize);

		// add it to free list
		m_AllBuffers.AddLast(pBuffer);
		m_FreeBuffers.AddLast(pBuffer);
	}

	return (XN_STATUS_OK);
}
void XnSharedMemoryBufferPool::Free()
{
	if (m_hSharedMemory != NULL)
	{
		xnOSCloseSharedMemory(m_hSharedMemory);
		m_hSharedMemory = NULL;
	}

	for (XnBuffersList::Iterator it = m_AllBuffers.begin(); it != m_AllBuffers.end(); ++it)
	{
		XnBufferInPool* pBuffer = *it;
		XN_DELETE(pBuffer);
	}

	m_AllBuffers.Clear();
	m_FreeBuffers.Clear();
	XnBufferPool::Free();
}
XnStatus XnSensorAudioStream::Free()
{
	m_Helper.Free();
	XnAudioStream::Free();
	if (m_hSharedMemory != NULL)
	{
		xnOSCloseSharedMemory(m_hSharedMemory);
		m_hSharedMemory = NULL;
	}

	// close critical sections
	if (m_buffer.hLock != NULL)
	{
		xnOSCloseCriticalSection(&m_buffer.hLock);
		m_buffer.hLock = NULL;
	}

	return (XN_STATUS_OK);
}