fixed several bugs
This commit is contained in:
+5
-2
@@ -234,11 +234,12 @@ int epicsShareAPI ca_search_and_connect (const char *name_str, chid *chanptr,
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
|
||||
if ( pcac->createChannel ( name_str, *pChan ) ) {
|
||||
if ( pcac->createChannelIO ( name_str, *pChan ) ) {
|
||||
*chanptr = pChan;
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
else {
|
||||
pChan->destroy ();
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
}
|
||||
@@ -380,7 +381,9 @@ int epicsShareAPI ca_add_masked_array_event (chtype type, unsigned long count, c
|
||||
|
||||
status = pChan->subscribe ( type, count, mask, *pSubsr );
|
||||
if ( status == ECA_NORMAL ) {
|
||||
if(monixptr) *monixptr = pSubsr;
|
||||
if ( monixptr ) {
|
||||
*monixptr = pSubsr;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
+44
-44
@@ -93,64 +93,56 @@ int acctst (char *pname)
|
||||
char pstring[NUM][MAX_STRING_SIZE];
|
||||
unsigned monCount=0u;
|
||||
|
||||
SEVCHK(ca_task_initialize(), "Unable to initialize");
|
||||
SEVCHK ( ca_task_initialize(), "Unable to initialize" );
|
||||
|
||||
conn_cb_count = 0;
|
||||
|
||||
printf("begin\n");
|
||||
printf ( "begin\n" );
|
||||
|
||||
printf("CA Client V%s\n", ca_version());
|
||||
printf ( "CA Client V%s\n", ca_version () );
|
||||
|
||||
/*
|
||||
* CA pend event delay accuracy test
|
||||
* (CA asssumes that search requests can be sent
|
||||
* at least every 25 mS on all supported os)
|
||||
*/
|
||||
pend_event_delay_test(1.0);
|
||||
pend_event_delay_test(0.1);
|
||||
pend_event_delay_test(0.25);
|
||||
pend_event_delay_test ( 1.0 );
|
||||
pend_event_delay_test ( 0.1 );
|
||||
pend_event_delay_test ( 0.25 );
|
||||
|
||||
/*
|
||||
* verify that we dont print a disconnect message when
|
||||
* we delete the last channel
|
||||
* (this fails if we see a disconnect message)
|
||||
*/
|
||||
status = ca_search( pname, &chix3);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_pend_io(1000.0);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_clear_channel(chix3);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_search ( pname, &chix3 );
|
||||
SEVCHK ( status, NULL );
|
||||
status = ca_pend_io ( 1000.0 );
|
||||
SEVCHK ( status, NULL );
|
||||
status = ca_clear_channel ( chix3 );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
/*
|
||||
* verify lots of disconnects
|
||||
* verify channel connected state variables
|
||||
*/
|
||||
printf("Connect/disconnect test");
|
||||
fflush(stdout);
|
||||
for (i = 0; i < 10; i++) {
|
||||
printf ( "Connect/disconnect test" );
|
||||
fflush ( stdout );
|
||||
for ( i = 0; i < 10; i++ ) {
|
||||
|
||||
status = ca_search(
|
||||
pname,
|
||||
&chix3);
|
||||
status = ca_search ( pname, &chix3 );
|
||||
SEVCHK(status, NULL);
|
||||
|
||||
status = ca_search(
|
||||
pname,
|
||||
&chix4);
|
||||
status = ca_search ( pname, &chix4 );
|
||||
SEVCHK(status, NULL);
|
||||
|
||||
status = ca_search(
|
||||
pname,
|
||||
&chix2);
|
||||
status = ca_search ( pname, &chix2 );
|
||||
SEVCHK(status, NULL);
|
||||
|
||||
status = ca_search(
|
||||
pname,
|
||||
&chix1);
|
||||
status = ca_search ( pname, &chix1 );
|
||||
SEVCHK(status, NULL);
|
||||
|
||||
if (ca_test_io() == ECA_IOINPROGRESS) {
|
||||
if ( ca_test_io() == ECA_IOINPROGRESS ) {
|
||||
assert(INVALID_DB_REQ(ca_field_type(chix1)) == TRUE);
|
||||
assert(INVALID_DB_REQ(ca_field_type(chix2)) == TRUE);
|
||||
assert(INVALID_DB_REQ(ca_field_type(chix3)) == TRUE);
|
||||
@@ -210,6 +202,14 @@ int acctst (char *pname)
|
||||
status = ca_search ( pname, &chix4 );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
/*
|
||||
* verify that NULL
|
||||
* evid does not cause failure
|
||||
*/
|
||||
status = ca_add_event ( DBR_FLOAT,
|
||||
chix4, EVENT_ROUTINE, NULL, NULL );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
status = ca_clear_channel ( chix4 );
|
||||
SEVCHK ( status, NULL );
|
||||
|
||||
@@ -615,34 +615,34 @@ int acctst (char *pname)
|
||||
* verify we dont jam up on many uninterrupted
|
||||
* put callback solicitations
|
||||
*/
|
||||
if(ca_write_access(chix1) && ca_v42_ok(chix1)){
|
||||
unsigned count=0u;
|
||||
printf ("Performing multiple put callback test...");
|
||||
fflush (stdout);
|
||||
for(i=0; i<10000; i++){
|
||||
if ( ca_write_access (chix1) && ca_v42_ok (chix1) ) {
|
||||
unsigned count = 0u;
|
||||
printf ( "Performing multiple put callback test..." );
|
||||
fflush ( stdout );
|
||||
for ( i=0; i<10000; i++ ) {
|
||||
dbr_float_t fval = 3.3F;
|
||||
status = ca_array_put_callback (
|
||||
DBR_FLOAT, 1, chix1, &fval,
|
||||
null_event, &count);
|
||||
SEVCHK (status, NULL);
|
||||
null_event, &count );
|
||||
SEVCHK ( status, NULL );
|
||||
}
|
||||
SEVCHK(ca_flush_io(), NULL);
|
||||
while (count<10000u) {
|
||||
ca_pend_event(1.0);
|
||||
printf("waiting...");
|
||||
fflush(stdout);
|
||||
SEVCHK ( ca_flush_io (), NULL );
|
||||
while ( count < 10000u ) {
|
||||
ca_pend_event ( 1.0 );
|
||||
printf ( "waiting..." );
|
||||
fflush ( stdout );
|
||||
}
|
||||
|
||||
printf("done.\n");
|
||||
printf ( "done.\n" );
|
||||
}
|
||||
else{
|
||||
printf("Skipped multiple put cb test - no write access\n");
|
||||
else {
|
||||
printf ( "Skipped multiple put cb test - no write access\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
* verify that we detect that a large string has been written
|
||||
*/
|
||||
if(ca_write_access(chix1)){
|
||||
if ( ca_write_access (chix1) ) {
|
||||
dbr_string_t stimStr;
|
||||
dbr_string_t respStr;
|
||||
memset(stimStr, 'a', sizeof(stimStr));
|
||||
|
||||
+11
-4
@@ -632,7 +632,7 @@ int cac::pendPrivate (double timeout, int early)
|
||||
|
||||
this->flush ();
|
||||
|
||||
if (this->pndrecvcnt==0u && early) {
|
||||
if ( this->pndrecvcnt == 0u && early ) {
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
@@ -785,12 +785,18 @@ void cac::registerService ( cacServiceIO &service )
|
||||
this->services.registerService ( service );
|
||||
}
|
||||
|
||||
bool cac::createChannel (const char *pName, cacChannel &chan)
|
||||
bool cac::createChannelIO (const char *pName, cacChannel &chan)
|
||||
{
|
||||
if ( this->services.createChannel (pName, chan) ) {
|
||||
cacChannelIO *pIO;
|
||||
|
||||
pIO = this->services.createChannelIO ( pName, chan );
|
||||
if ( pIO ) {
|
||||
chan.attachIO ( *pIO );
|
||||
return true;
|
||||
}
|
||||
if ( cacGlobalServiceList.createChannel (pName, chan) ) {
|
||||
pIO = cacGlobalServiceList.createChannelIO ( pName, chan );
|
||||
if ( pIO ) {
|
||||
chan.attachIO ( *pIO );
|
||||
return true;
|
||||
}
|
||||
if ( ! this->pudpiiu ) {
|
||||
@@ -806,6 +812,7 @@ bool cac::createChannel (const char *pName, cacChannel &chan)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
chan.attachIO ( *pNetChan );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
cacChannelIO::cacChannelIO ( cacChannel &chanIn ) :
|
||||
chan ( chanIn )
|
||||
{
|
||||
chan.attachIO ( *this );
|
||||
}
|
||||
|
||||
cacChannelIO::~cacChannelIO ()
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ class cacServiceList : private osiMutex {
|
||||
public:
|
||||
epicsShareFunc cacServiceList ();
|
||||
epicsShareFunc void registerService ( cacServiceIO &service );
|
||||
epicsShareFunc bool createChannel (const char *pName, cacChannel &chan);
|
||||
epicsShareFunc cacChannelIO * createChannelIO (const char *pName, cacChannel &chan);
|
||||
private:
|
||||
tsDLList <cacServiceIO> services;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ void cacServiceList::registerService ( cacServiceIO &service )
|
||||
this->unlock ();
|
||||
}
|
||||
|
||||
bool cacServiceList::createChannel (const char *pName, cacChannel &chan)
|
||||
cacChannelIO * cacServiceList::createChannelIO (const char *pName, cacChannel &chan)
|
||||
{
|
||||
cacChannelIO *pChanIO = 0;
|
||||
|
||||
@@ -45,11 +45,6 @@ bool cacServiceList::createChannel (const char *pName, cacChannel &chan)
|
||||
}
|
||||
this->unlock ();
|
||||
|
||||
if ( pChanIO ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return pChanIO;
|
||||
}
|
||||
|
||||
|
||||
+8
-5
@@ -209,6 +209,9 @@ public:
|
||||
static void * operator new ( size_t size );
|
||||
static void operator delete ( void *pCadaver, size_t size );
|
||||
|
||||
int subscriptionMsg ( unsigned subscriptionId,
|
||||
unsigned typeIn, unsigned long countIn, unsigned short maskIn );
|
||||
|
||||
tsDLList
|
||||
<class baseNMIU> eventq;
|
||||
class netiiu *piiu;
|
||||
@@ -227,7 +230,7 @@ private:
|
||||
unsigned f_fullyConstructed:1;
|
||||
static tsFreeList < class nciu, 1024 > freeList;
|
||||
~nciu (); // force pool allocation
|
||||
int nciu::issuePut ( ca_uint16_t cmd, unsigned id, chtype type,
|
||||
int issuePut ( ca_uint16_t cmd, unsigned id, chtype type,
|
||||
unsigned long count, const void *pvalue );
|
||||
};
|
||||
|
||||
@@ -391,7 +394,7 @@ public:
|
||||
class netiiu : public baseIIU {
|
||||
public:
|
||||
netiiu (class cac *pcac);
|
||||
~netiiu ();
|
||||
virtual ~netiiu ();
|
||||
void show (unsigned level) const;
|
||||
|
||||
virtual bool compareIfTCP (nciu &chan, const sockaddr_in &) const = 0;
|
||||
@@ -456,7 +459,7 @@ private:
|
||||
class udpiiu : public netiiu {
|
||||
public:
|
||||
udpiiu (cac *pcac);
|
||||
~udpiiu ();
|
||||
virtual ~udpiiu ();
|
||||
void shutdown ();
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
bool ca_v42_ok () const;
|
||||
@@ -718,7 +721,7 @@ private:
|
||||
class cac : public caClient {
|
||||
public:
|
||||
cac ();
|
||||
~cac ();
|
||||
virtual ~cac ();
|
||||
void safeDestroyNMIU (unsigned id);
|
||||
void processRecvBacklog ();
|
||||
void flush ();
|
||||
@@ -756,7 +759,7 @@ public:
|
||||
void installCASG (CASG &);
|
||||
void uninstallCASG (CASG &);
|
||||
void registerService ( cacServiceIO &service );
|
||||
bool createChannel (const char *name_str, cacChannel &chan);
|
||||
bool createChannelIO (const char *name_str, cacChannel &chan);
|
||||
|
||||
osiTimerQueue timerQueue;
|
||||
ELLLIST activeCASGOP;
|
||||
|
||||
+59
-3
@@ -497,7 +497,7 @@ int nciu::write (unsigned type, unsigned long countIn, const void *pValue, cacNo
|
||||
|
||||
UNLOCK (this->piiu->pcas);
|
||||
|
||||
status = this->issuePut (CA_PROTO_WRITE_NOTIFY, id,
|
||||
status = this->issuePut (CA_PROTO_WRITE_NOTIFY, newId,
|
||||
type, countIn, pValue);
|
||||
if ( status != ECA_NORMAL ) {
|
||||
/*
|
||||
@@ -567,10 +567,10 @@ unsigned long nciu::nativeElementCount () const
|
||||
|
||||
channel_state nciu::state () const
|
||||
{
|
||||
if (this->f_connected) {
|
||||
if ( this->f_connected ) {
|
||||
return cs_conn;
|
||||
}
|
||||
else if (this->previousConn) {
|
||||
else if ( this->previousConn ) {
|
||||
return cs_prev_conn;
|
||||
}
|
||||
else {
|
||||
@@ -840,3 +840,59 @@ void nciu::decrementOutstandingIO ( unsigned seqNumber )
|
||||
{
|
||||
this->piiu->pcas->decrementOutstandingIO ( seqNumber );
|
||||
}
|
||||
|
||||
int nciu::subscriptionMsg ( unsigned subscriptionId, unsigned typeIn,
|
||||
unsigned long countIn, unsigned short maskIn)
|
||||
{
|
||||
int status;
|
||||
struct monops msg;
|
||||
ca_float32_t p_delta;
|
||||
ca_float32_t n_delta;
|
||||
ca_float32_t tmo;
|
||||
|
||||
/*
|
||||
* clip to the native count and set to the native count if they
|
||||
* specify zero
|
||||
*/
|
||||
if ( countIn > this->count ){
|
||||
countIn = this->count;
|
||||
}
|
||||
|
||||
/*
|
||||
* dont allow overflow when converting to ca_uint16_t
|
||||
*/
|
||||
if ( countIn > 0xffff ) {
|
||||
countIn = 0xffff;
|
||||
}
|
||||
|
||||
/* msg header */
|
||||
msg.m_header.m_cmmd = htons ( CA_PROTO_EVENT_ADD );
|
||||
msg.m_header.m_available = subscriptionId;
|
||||
msg.m_header.m_dataType =
|
||||
htons ( static_cast <ca_uint16_t> ( typeIn ) );
|
||||
msg.m_header.m_count =
|
||||
htons ( static_cast <ca_uint16_t> ( countIn ) );
|
||||
msg.m_header.m_cid = this->sid;
|
||||
msg.m_header.m_postsize = sizeof ( msg.m_info );
|
||||
|
||||
/* msg body */
|
||||
p_delta = 0.0;
|
||||
n_delta = 0.0;
|
||||
tmo = 0.0;
|
||||
dbr_htonf ( &p_delta, &msg.m_info.m_hval );
|
||||
dbr_htonf ( &n_delta, &msg.m_info.m_lval );
|
||||
dbr_htonf ( &tmo, &msg.m_info.m_toval );
|
||||
msg.m_info.m_mask = htons ( maskIn );
|
||||
msg.m_info.m_pad = 0; /* allow future use */
|
||||
|
||||
LOCK ( this->piiu->pcas );
|
||||
if ( this->f_connected ) {
|
||||
status = this->piiu->pushStreamMsg ( &msg.m_header, &msg.m_info, true );
|
||||
}
|
||||
else {
|
||||
status = ECA_NORMAL;
|
||||
}
|
||||
UNLOCK ( this->piiu->pcas );
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -53,51 +53,8 @@ void netSubscription::destroy()
|
||||
|
||||
int netSubscription::subscriptionMsg ()
|
||||
{
|
||||
unsigned long tmpCount;
|
||||
struct monops msg;
|
||||
ca_float32_t p_delta;
|
||||
ca_float32_t n_delta;
|
||||
ca_float32_t tmo;
|
||||
|
||||
/*
|
||||
* clip to the native count and set to the native count if they
|
||||
* specify zero
|
||||
*/
|
||||
if ( this->count > this->chan.nativeElementCount () ){
|
||||
tmpCount = this->chan.nativeElementCount ();
|
||||
}
|
||||
else {
|
||||
tmpCount = this->count;
|
||||
}
|
||||
|
||||
/*
|
||||
* dont allow overflow when converting to ca_uint16_t
|
||||
*/
|
||||
if ( tmpCount > 0xffff ) {
|
||||
tmpCount = 0xffff;
|
||||
}
|
||||
|
||||
/* msg header */
|
||||
msg.m_header.m_cmmd = htons (CA_PROTO_EVENT_ADD);
|
||||
msg.m_header.m_available = this->id;
|
||||
msg.m_header.m_dataType =
|
||||
htons ( static_cast <ca_uint16_t> (this->type) );
|
||||
msg.m_header.m_count =
|
||||
htons ( static_cast <ca_uint16_t> ( tmpCount ) );
|
||||
msg.m_header.m_cid = this->chan.sid;
|
||||
msg.m_header.m_postsize = sizeof ( msg.m_info );
|
||||
|
||||
/* msg body */
|
||||
p_delta = 0.0;
|
||||
n_delta = 0.0;
|
||||
tmo = 0.0;
|
||||
dbr_htonf (&p_delta, &msg.m_info.m_hval);
|
||||
dbr_htonf (&n_delta, &msg.m_info.m_lval);
|
||||
dbr_htonf (&tmo, &msg.m_info.m_toval);
|
||||
msg.m_info.m_mask = htons (this->mask);
|
||||
msg.m_info.m_pad = 0; /* allow future use */
|
||||
|
||||
return this->chan.piiu->pushStreamMsg (&msg.m_header, &msg.m_info, true);
|
||||
return this->chan.subscriptionMsg ( this->id, this->type,
|
||||
this->count, this->mask );
|
||||
}
|
||||
|
||||
void netSubscription::disconnect ( const char * /* pHostName */ )
|
||||
|
||||
@@ -167,6 +167,4 @@ void * oldChannel::operator new ( size_t size )
|
||||
void oldChannel::operator delete ( void *pCadaver, size_t size )
|
||||
{
|
||||
oldChannel::freeList.release ( pCadaver, size );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user