//-----------------------------------------------------------------------------
// Copyright (c) 1994,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:
//      cdevRequestObject implementation (abstract class)
//      inline functions	
//
// Author:  Jie Chen & Chip Watson
//
// Revision History:
//   cdevRequestObject.i,v
// Revision 1.3  1998/02/13  14:00:44  chen
// add ref and deref
//
// Revision 1.2  1997/03/03  17:52:28  chen
// add buffering mechanism to caService
//
// Revision 1.1  1995/12/08  15:39:43  chen
// inline functions
//
//

// Note: How to determine to buffer an exeution object?
//       If an execution object belongs to a group with 
//       an immediate execution mode, this object will not be
//       buffered. If an execution object belongs to a group
//       with a deferred execution mode, this execution object
//       will be buffered

INLINE
int
cdevRequestObject::deferExecution (cdevData* out, cdevData* result)
{
  if (executionMode () == CDEV_EXEC_DEFERRED) { 
    // create a transaction object
    cdevExecObj* obj = new cdevExecObj (&system_, this, out, result, 0);
    return 1;
  }
  else
    return 0;
}

INLINE
int
cdevRequestObject::deferExecution (cdevData* out, cdevCallback* callback)
{
  if (executionMode () == CDEV_EXEC_DEFERRED) { 
    // create a transaction object with new copy of callback
    // must clone the data, as the caller did not
    cdevCallback *ccbk = new cdevCallback (*callback);
    cdevData *cloned = new cdevData(*out);
    cdevExecObj* obj = new cdevExecObj (&system_, this, cloned, 0, ccbk);
    return 1;
  }
  else
    return 0;
}

INLINE
void
cdevRequestObject::bufferExecution (cdevData* out, cdevData* result,
				    cdevGroup* group, void* arg)
{
  // create an execution object that is registered to the group
  // caller has already cloned the data, so don't need to
  cdevExecObj* obj = new cdevExecObj (&system_, this, out, result, 0,
				      group, arg);
}

INLINE
void
cdevRequestObject::bufferExecution (cdevData* out, cdevCallback* callback,
				    cdevGroup* group, void* arg)
{
  // create an execution object that is registered to the group
  // caller has already cloned the data, so don't need to
  cdevExecObj* obj = new cdevExecObj (&system_, this, out, 0, callback,
				      group, arg);
}

INLINE
int
cdevRequestObject::execNoBlock (cdevData*, cdevData*, void* )
{
  // empty: derived class handles this
  return CDEV_SUCCESS;
}

INLINE
int
cdevRequestObject::execCallback (cdevData*, cdevCallback&, void* )
{
  // empty: derived class handles this
  return CDEV_SUCCESS;
}

//=======================================================================
//   clear a long mask, set every bit to 0
//=======================================================================
INLINE
void cdevMaskZero (long& p)
{
  ::memset ((char *)&p, (char)0, sizeof (long));
}

//=======================================================================
//   turn on a bit at position n inside the mask p
//=======================================================================
INLINE
void cdevMaskSet (long n, long& p)
{
  assert ((n >= 0) && (n < sizeof (long) * NUMBITS_PER_BYTE));
  p |= 1 << n;
}

//=======================================================================
//   turn off a bit at position n inside the mask p
//=======================================================================
INLINE
void cdevMaskClr (long n, long& p)
{
  assert ((n >= 0) && (n < sizeof (long) * NUMBITS_PER_BYTE));
  p &= ~(1 << n);
}

//=======================================================================  
//   check whether a bit n is set or not
//=======================================================================
INLINE
int cdevMaskIsSet (long n, long p)
{
  assert ((n >= 0) && (n < sizeof (long) * NUMBITS_PER_BYTE));
  return (p & (1 << n));
}

INLINE
void cdevRequestObject::ref (void)
{
  refCount_ ++;
}

INLINE
void cdevRequestObject::deref (void)
{
  refCount_ --;
}


