improved performance

This commit is contained in:
Jeff Hill
2000-11-08 03:52:18 +00:00
parent 2ded135da9
commit 4784b73a9f
39 changed files with 2480 additions and 2589 deletions

View File

@@ -59,22 +59,13 @@
#include "iocinf.h"
#include "comBuf_IL.h"
#include "comQueSend_IL.h"
tsFreeList < class comBuf, 0x20 > comBuf::freeList;
// nill message pad bytes
static const char nillBytes [] =
{
0, 0, 0, 0,
0, 0, 0, 0
};
inline bufferReservoir::~bufferReservoir ()
{
comBuf *pBuf;
while ( ( pBuf = this->reservedBufs.get () ) ) {
pBuf->destroy ();
}
this->drain ();
}
inline comBuf *bufferReservoir::fetchOneBuffer ()
@@ -99,47 +90,49 @@ inline unsigned bufferReservoir::nBytes ()
return ( this->reservedBufs.count () * comBuf::maxBytes () );
}
comQueSend::comQueSend ( wireSendAdapter & wireIn ) :
wire ( wireIn ), nBytesPending ( 0u )
{
}
comQueSend::~comQueSend ()
{
this->clear ();
}
void comQueSend::clear ()
{
comBuf *pBuf;
while ( ( pBuf = this->bufs.get () ) ) {
this->nBytesPending -= pBuf->occupiedBytes ();
pBuf->destroy ();
}
this->reservoir.drain ();
}
// reserve sufficent space for entire message
// (this allows the recv thread to add a message
// to the que while some other thread is flushing
// and therefore prevents deadlocks, and it also
// allows proper status to be returned)
inline int comQueSend::lockAndReserveSpace ( unsigned msgSize,
bufferReservoir &reservoir, bool enablePreemptionDuringFlush )
int comQueSend::reserveSpace ( unsigned msgSize )
{
unsigned bytesReserved = reservoir.nBytes ();
unsigned bytesReserved;
this->mutex.lock ();
bytesReserved = this->reservoir.nBytes ();
while ( true ) {
comBuf *pComBuf = this->bufs.last ();
if ( pComBuf ) {
bytesReserved += pComBuf->unoccupiedBytes ();
}
if ( bytesReserved >= msgSize || this->bufs.count () < 4 ) {
break;
}
if ( ! this->flushToWirePermit () ) {
if ( this->bufs.count () >= 32u ) {
this->mutex.unlock ();
return ECA_TOLARGE;
}
break;
}
this->mutex.unlock ();
this->flushToWire ( enablePreemptionDuringFlush );
this->mutex.lock ();
comBuf *pComBuf = this->bufs.last ();
if ( pComBuf ) {
bytesReserved += pComBuf->unoccupiedBytes ();
}
while ( bytesReserved < msgSize ) {
if ( reservoir.addOneBuffer() ) {
if ( reservoir.addOneBuffer () ) {
bytesReserved += comBuf::maxBytes ();
}
else {
this->mutex.unlock ();
return ECA_ALLOCMEM;
}
}
@@ -147,100 +140,43 @@ inline int comQueSend::lockAndReserveSpace ( unsigned msgSize,
return ECA_NORMAL;
}
// 1) This routine is private because it assumes that the lock
// is applied
//
// 2) This routine does not return status because of the following
// argument. The routine can fail because the wire disconnects or
// because their isnt memory to create a buffer. For the former we
// just discard the message, but do not fail. For the latter we
// shutdown() the connection and discard the rest of the message
// (this eliminates the possibility of message fragments getting
// onto the wire).
//
// 3) Arguments here are a bit verbose until compilers all implement
// member template functions.
//
template < class T >
inline void comQueSend_copyIn ( tsDLList < comBuf > &comBufList,
bufferReservoir &reservoir, const T *pVal, unsigned nElem )
void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem )
{
unsigned nCopied;
comBuf *pComBuf = comBufList.last ();
if ( pComBuf ) {
nCopied = pComBuf->copyIn ( pVal, nElem );
}
else {
nCopied = 0u;
}
while ( nElem > nCopied ) {
pComBuf = reservoir.fetchOneBuffer ();
//
// This fails only if space was not preallocated.
// See comments at the top of this program on
// why space must always be preallocated.
//
assert ( pComBuf );
nCopied += pComBuf->copyIn ( &pVal[nCopied], nElem - nCopied );
comBufList.add ( *pComBuf );
}
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_string_t *> ( pValue ), nElem );
}
template < class T >
inline void comQueSend_copyIn ( tsDLList < comBuf > &comBufList, bufferReservoir &reservoir, const T &val )
void comQueSend::copy_dbr_short ( const void *pValue, unsigned nElem )
{
comBuf *pComBuf = comBufList.last ();
if ( pComBuf ) {
if ( pComBuf->copyIn ( &val, 1u ) >= 1u ) {
return;
}
}
pComBuf = reservoir.fetchOneBuffer ();
//
// This fails only if space was not preallocated.
// See comments at the top of this program on
// space must always be preallocated.
//
assert ( pComBuf );
pComBuf->copyIn ( &val, 1u );
comBufList.add ( *pComBuf );
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_short_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_string ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_float ( const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_string_t *> ( pValue ), nElem );
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_float_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_short ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_char ( const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_short_t *> ( pValue ), nElem );
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_char_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_float ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_long ( const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_float_t *> ( pValue ), nElem );
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_long_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_char ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
void comQueSend::copy_dbr_double ( const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_char_t *> ( pValue ), nElem );
comQueSend_copyIn ( this->nBytesPending, this->bufs, this->reservoir,
static_cast <const dbr_double_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_long ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_long_t *> ( pValue ), nElem );
}
void comQueSend::copy_dbr_double ( bufferReservoir &reservoir, const void *pValue, unsigned nElem )
{
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const dbr_double_t *> ( pValue ), nElem );
}
const comQueSend::copyFunc_t comQueSend::dbrCopyVector [] = {
const comQueSend::copyFunc_t comQueSend::dbrCopyVector [39] = {
&comQueSend::copy_dbr_string,
&comQueSend::copy_dbr_short,
&comQueSend::copy_dbr_float,
@@ -282,536 +218,3 @@ const comQueSend::copyFunc_t comQueSend::dbrCopyVector [] = {
0 // DBR_CLASS_NAME
};
comQueSend::~comQueSend ()
{
comBuf *pBuf;
this->mutex.lock ();
while ( ( pBuf = this->bufs.get () ) ) {
pBuf->destroy ();
}
this->mutex.unlock ();
}
unsigned comQueSend::occupiedBytes () const
{
this->mutex.lock ();
unsigned count = this->bufs.count ();
unsigned nBytes;
if ( count >= 2u ) {
nBytes = this->bufs.first ()->occupiedBytes ();
nBytes += this->bufs.last ()->occupiedBytes ();
nBytes += ( count - 2u ) * comBuf::maxBytes ();
}
else if ( count == 1u ) {
nBytes = this->bufs.first ()->occupiedBytes ();
}
else {
nBytes = 0u;
}
this->mutex.unlock ();
return nBytes;
}
bool comQueSend::flushToWire ( bool enablePreemptionDuringFlush )
{
bool success = false;
// the recv thread is not permitted to flush as this
// can result in a push / pull deadlock on the TCP pipe,
// but in that case this does schedual the flush through
// the higher priority send thread
if ( ! this->flushToWirePermit () ) {
return true;
}
// this approach requires that only one thread at a time
// performs flushes but its advantage is that the primary
// lock is not held while sending and this prevents deadlocks
this->flushMutex.lock ();
while ( true ) {
this->mutex.lock ();
comBuf * pBuf = this->bufs.get ();
this->mutex.unlock ();
if ( ! pBuf ) {
success = true;
break;
}
success = pBuf->flushToWire ( *this, enablePreemptionDuringFlush );
pBuf->destroy ();
if ( ! success ) {
this->mutex.lock ();
while ( ( pBuf = this->bufs.get () ) ) {
pBuf->destroy ();
}
this->mutex.unlock ();
break;
}
}
this->flushMutex.unlock ();
return success;
}
int comQueSend::writeRequest ( unsigned serverId, unsigned type, unsigned nElem, const void *pValue )
{
bufferReservoir reservoir;
unsigned size, postcnt;
bool stringOptim;
if ( type < 0 || type >= NELEMENTS ( this->dbrCopyVector ) ) {
return ECA_BADTYPE;
}
if ( ! this->dbrCopyVector [type] ) {
return ECA_BADTYPE;
}
if ( nElem > 0xffff) {
return ECA_BADCOUNT;
}
if ( type == DBR_STRING && nElem == 1 ) {
char *pstr = (char *) pValue;
size = strlen ( pstr ) +1;
stringOptim = true;
}
else {
size = dbr_size_n ( type, nElem );
stringOptim = false;
}
postcnt = CA_MESSAGE_ALIGN ( size );
if ( postcnt > 0xffff ) {
return ECA_BADCOUNT;
}
assert ( serverId <= 0xffffffff );
int status = this->lockAndReserveSpace ( postcnt + 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_WRITE ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( postcnt ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( ~0UL ) ); // available
if ( stringOptim ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <const unsigned char *> ( pValue ), size );
}
else {
( this->*dbrCopyVector [type] ) ( reservoir, pValue, nElem );
}
comQueSend_copyIn ( this->bufs, reservoir, nillBytes, postcnt - size );
this->mutex.unlock ();
}
return status;
}
int comQueSend::writeNotifyRequest ( unsigned ioId, unsigned serverId, unsigned type, unsigned nElem, const void *pValue )
{
bufferReservoir reservoir;
ca_uint32_t size, postcnt;
if ( type < 0 || type >= NELEMENTS ( this->dbrCopyVector ) ) {
return ECA_BADTYPE;
}
if ( ! this->dbrCopyVector [type] ) {
return ECA_BADTYPE;
}
if ( nElem > 0xffff) {
return ECA_BADCOUNT;
}
if ( type == DBR_STRING && nElem == 1 ) {
char *pstr = (char *) pValue;
size = strlen ( pstr ) +1;
}
else {
size = dbr_size_n ( type, nElem );
}
postcnt = CA_MESSAGE_ALIGN ( size );
if ( postcnt > 0xffff ) {
return ECA_BADCOUNT;
}
assert ( serverId <= 0xffffffff );
int status = this->lockAndReserveSpace ( postcnt + 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_WRITE_NOTIFY ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( postcnt ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( ioId ) ); // available
( this->*dbrCopyVector [type] ) ( reservoir, pValue, nElem );
comQueSend_copyIn ( this->bufs, reservoir, nillBytes, postcnt - size );
this->mutex.unlock ();
}
return status;
}
int comQueSend::readCopyRequest ( unsigned ioId, unsigned serverId, unsigned type, unsigned nElem )
{
bufferReservoir reservoir;
if ( nElem > 0xffff) {
return ECA_BADCOUNT;
}
if ( type > 0xffff) {
return ECA_BADTYPE;
}
assert ( serverId <= 0xffffffff );
int status = this->lockAndReserveSpace ( 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_READ ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( ioId ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::readNotifyRequest ( unsigned ioId, unsigned serverId, unsigned type, unsigned nElem )
{
bufferReservoir reservoir;
if ( nElem > 0xffff) {
return ECA_BADCOUNT;
}
if ( type > 0xffff) {
return ECA_BADTYPE;
}
assert ( serverId <= 0xffffffff );
int status = this->lockAndReserveSpace ( 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_READ_NOTIFY ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( ioId ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::createChannelRequest ( unsigned id, const char *pName, unsigned nameLength )
{
bufferReservoir reservoir;
unsigned postCnt = CA_MESSAGE_ALIGN ( nameLength );
assert ( id <= 0xffffffff );
assert ( postCnt <= 0xffff );
int status = this->lockAndReserveSpace ( postCnt + 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_CLAIM_CIU ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( postCnt ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( id ) ); // cid
//
// The available field is used (abused)
// here to communicate the minor version number
// starting with CA 4.1.
//
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( CA_MINOR_VERSION ) ); // available
if ( nameLength ) {
comQueSend_copyIn ( this->bufs, reservoir, pName, nameLength );
}
if ( postCnt > nameLength ) {
comQueSend_copyIn ( this->bufs, reservoir, nillBytes, postCnt - nameLength );
}
this->mutex.unlock ();
}
return status;
}
int comQueSend::clearChannelRequest ( unsigned clientId, unsigned serverId )
{
bufferReservoir reservoir;
assert ( serverId <= 0xffffffff );
assert ( clientId <= 0xffffffff );
int status = this->lockAndReserveSpace ( 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_CLEAR_CHANNEL ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( clientId ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::subscriptionRequest ( unsigned ioId, unsigned serverId,
unsigned type, unsigned nElem, unsigned mask, bool enablePreemptionDuringFlush )
{
bufferReservoir reservoir;
if ( nElem > 0xffff) {
return ECA_BADCOUNT;
}
if ( type > 0xffff) {
return ECA_BADTYPE;
}
assert ( serverId <= 0xffffffff );
assert ( ioId <= 0xffffffff );
int status = this->lockAndReserveSpace ( 32u, reservoir, enablePreemptionDuringFlush );
if ( status == ECA_NORMAL ) {
// header
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_EVENT_ADD ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 16u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( ioId ) ); // available
// extension
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_float32_t > ( 0.0 ) ); // m_lval
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_float32_t > ( 0.0 ) ); // m_hval
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_float32_t > ( 0.0 ) ); // m_toval
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( mask ) ); // m_mask
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( 0u ) ); // m_pad
this->mutex.unlock ();
}
return status;
}
int comQueSend::subscriptionCancelRequest ( unsigned ioId, unsigned serverId, unsigned type, unsigned nElem )
{
bufferReservoir reservoir;
assert ( type <= 0xffff );
assert ( nElem <= 0xffff );
assert ( serverId <= 0xffffffff );
assert ( ioId <= 0xffffffff );
int status = this->lockAndReserveSpace ( 16u, reservoir, true );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( CA_PROTO_EVENT_CANCEL ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( type ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint16_t > ( nElem ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint32_t > ( serverId ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast < ca_uint32_t > ( ioId ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::disableFlowControlRequest ()
{
bufferReservoir reservoir;
int status = this->lockAndReserveSpace ( 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_EVENTS_ON ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::enableFlowControlRequest ()
{
bufferReservoir reservoir;
int status = this->lockAndReserveSpace ( 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_EVENTS_OFF ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::noopRequest ()
{
bufferReservoir reservoir;
int status = this->lockAndReserveSpace ( 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_NOOP ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::echoRequest ()
{
bufferReservoir reservoir;
int status = this->lockAndReserveSpace ( 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_ECHO ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
this->mutex.unlock ();
}
return status;
}
int comQueSend::hostNameSetRequest ( const char *pName )
{
bufferReservoir reservoir;
unsigned size = strlen ( pName ) + 1u;
unsigned postSize = CA_MESSAGE_ALIGN ( size );
assert ( postSize < 0xffff );
int status = this->lockAndReserveSpace ( postSize + 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_HOST_NAME ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( postSize ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
comQueSend_copyIn ( this->bufs, reservoir, pName, size );
comQueSend_copyIn ( this->bufs, reservoir, nillBytes, postSize - size );
this->mutex.unlock ();
}
return status;
}
int comQueSend::userNameSetRequest ( const char *pName )
{
bufferReservoir reservoir;
unsigned size = strlen ( pName ) + 1u;
unsigned postSize = CA_MESSAGE_ALIGN ( size );
assert ( postSize < 0xffff );
int status = this->lockAndReserveSpace ( postSize + 16u, reservoir, false );
if ( status == ECA_NORMAL ) {
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( CA_PROTO_CLIENT_NAME ) ); // cmd
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( postSize ) ); // postsize
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // dataType
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint16_t> ( 0u ) ); // count
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // cid
comQueSend_copyIn ( this->bufs, reservoir, static_cast <ca_uint32_t> ( 0u ) ); // available
comQueSend_copyIn ( this->bufs, reservoir, pName, size );
comQueSend_copyIn ( this->bufs, reservoir, nillBytes, postSize - size );
this->mutex.unlock ();
}
return status;
}
#ifdef JUNKYARD
/*
* tcpiiu::pushStreamMsg ()
*/
int tcpiiu::pushStreamMsg ( const caHdr &hdr, const void *pext, unsigned extsize )
{
unsigned alignedExtSize;
bool status;
msgDescriptor msgs[3];
caHdr msgHdr = hdr;
if ( extsize > 0xffff - 7 ) {
return ECA_TOLARGE;
}
alignedExtSize = CA_MESSAGE_ALIGN ( extsize );
msgHdr.m_postsize = htons ( alignedExtSize );
debugPrintf ( (
"CAC: Request => cmmd=%x cid=0x%x type=%x count=%x postsize=%x\n",
hdr.m_cmmd, hdr.m_cid, hdr.m_dataType,
hdr.m_count, hdr.m_postsize ) );
msgs[0].pBuf = &msgHdr;
msgs[0].nBytes = sizeof ( msgHdr );
msgs[1].pBuf = pext;
msgs[1].nBytes = extsize;
if ( alignedExtSize > extsize ) {
unsigned diff = alignedExtSize - extsize;
assert ( diff <= sizeof ( nullBuff ) );
msgs[2].pBuf = nullBuff;
msgs[2].nBytes = diff;
status = this->copyInBytes ( msgs, 3u );
}
else {
status = this->copyInBytes ( msgs, 2u );
}
if ( status ) {
return ECA_NORMAL;
}
else {
this->shutdown ();
return ECA_ALLOCMEM;
}
}
/*
* tcpiiu::pushStreamMsg ()
*/
int tcpiiu::pushStreamMsg ( const caHdr &hdr )
{
caHdr msgHdr = hdr;
msgHdr.m_postsize = htons ( 0 );
debugPrintf ( (
"CAC: Request => cmmd=%x cid=0x%x type=%x count=%x postsize=%x\n",
hdr.m_cmmd, hdr.m_cid, hdr.m_dataType,
hdr.m_count, hdr.m_postsize ) );
bool status = this->copyIn ( msgHdr );
if ( status ) {
return ECA_NORMAL;
}
else {
this->shutdown ();
return ECA_ALLOCMEM;
}
}
#endif