//-----------------------------------------------------------------------------
// Copyright (c) 1995      Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//	This header file contains the class definitions for the classes
//	associated with a cdevTranNode.  The cdevTranNode is an extension
// 	of the cdevTranObj.  It provides a mechanism for tracking allocated
// 	and unallocated cdevTranObj objects and prevents inadvertent writes
// 	to unallocated memory.
//
// Author:  Walt Akers
//
// Revision History:
//   cdevTranNode.cc,v
// Revision 1.1  1996/11/21  18:22:27  akers
// Non-Server Oriented Service
//
// Revision 1.1  1996/04/30  15:37:41  akers
// Simple CDEV Service
//
// Revision 1.1.1.1  1996/02/28  16:36:20  akers
// Initial release of support for ACE Services
//
// Revision 2.0  1995/10/04  19:21:37  withers
// New CVS repository
//
// Revision 1.1.1.1  1995/10/04  18:45:08  bickley
// CVS start of high-level apps
//
// Revision 1.1.1.1  1995/09/15  17:15:30  withers
// MODEL SERVICE SOURCE
//
//
#include <cdevTranNode.h>

// *****************************************************************************
// * Static class members requiring initialization.
// *****************************************************************************
int            cdevTranNode::count       = 0;
cdevTranNode * cdevTranNode::freeList    = NULL;
cdevTranNode * cdevTranNode::activeList  = NULL;
int            cdevTranNode::initialized = 1;

// *****************************************************************************
// * cdevTranNode::new :
// *	This is the internal mechanism that is used to allocate new cdevTranNode
// *	objects.  If an object is already available on the freelist, this 
// *	function will allocate from that list to the activeList.  Otherwise, a
// *	block of cdevTranNode objects will be allocated to repopulate the
// *	freeList first.
// *****************************************************************************
void * cdevTranNode::operator new ( size_t )
	{
	cdevTranNode * node;
	int i;
	
	if(freeList==NULL)
		{
		freeList = ::new cdevTranNode[16];
		for(i=0; i<16; i++)
			{
			freeList[i].next         = (i<15) ? &freeList[i+1] : NULL;
			freeList[i].allocated    = FALSE;
			freeList[i].finished_    = FALSE;
			freeList[i].transaction_ = 0;
			}
		cdevTranNode::count-=16;
		}
	node     = freeList;
	freeList = node->next;
	
	node->allocated = TRUE;
	node->next      = activeList;
	activeList      = node;
	
	return node;
	}
	
// *****************************************************************************
// * cdevTranNode::delete :
// *	This function is used to return an allocated cdevTranNode to the
// *	freeList for later allocation to another caller.  This function will
// *	clear the transaction flag and will clear the allocated flag.
// *****************************************************************************
void cdevTranNode::operator delete ( void * ptr )
	{
	cdevTranNode * node   = activeList;
	cdevTranNode * prev   = NULL;
	
	if(ptr != NULL)
		{
		while(node!=NULL && node!=(cdevTranNode *)ptr)
			{	
			prev = node;
			node = prev->next; 
			}
		if(node!=NULL)
			{
			if(prev) prev->next = node->next;
			else     activeList = node->next;
			}
		
		node               = (cdevTranNode *)ptr;
		node->allocated    = FALSE;
		node->finished_    = FALSE;
		node->transaction_ = 0;
		node->next         = freeList;
		freeList           = node;
		}
	}
	
// *****************************************************************************
// * cdevTranNode::find:
// *	Allows the caller to locate a cdevTranNode using the transaction number.
// *****************************************************************************
cdevTranNode * cdevTranNode::find ( int Transaction )
	{
	cdevTranNode * node = activeList;
	while(node!=NULL && node->transaction_ != Transaction)
		{
		node = node->next;
		}
	return node;
	}
	
// *****************************************************************************
// * cdevTranNode::init:
// *	Allows the caller to initialize static members of the cdevTranNode class
// *****************************************************************************
void cdevTranNode::init ( void )
	{
	if(!initialized)
		{
		count      = 0;
		freeList   = NULL;
		activeList = NULL;
		initialized = 1;
		}
	}
