access control mods

This commit is contained in:
Jeff Hill
1994-04-19 21:17:06 +00:00
parent e3a6072e15
commit 70ac733c8e
10 changed files with 496 additions and 165 deletions
+37 -2
View File
@@ -280,10 +280,12 @@ void *pext;
{
struct extmsg msg;
unsigned long bytesAvailable;
unsigned long actualextsize;
unsigned long extsize;
unsigned long bytesSent;
msg = *pmsg;
actualextsize = pmsg->m_postsize;
extsize = CA_MESSAGE_ALIGN(pmsg->m_postsize);
msg.m_postsize = htons(extsize);
@@ -342,8 +344,26 @@ void *pext;
bytesSent = cacRingBufferWrite(
&piiu->send,
pext,
extsize);
assert(bytesSent == extsize);
actualextsize);
assert(bytesSent == actualextsize);
/*
* force pad bytes at the end of the message to nill
* if present
*/
{
static nullBuff[32];
int n;
n = extsize-actualextsize;
if(n){
assert(n<=sizeof(nullBuff));
bytesSent = cacRingBufferWrite(
&piiu->send,
nullBuff,
n);
assert(bytesSent == n);
}
}
UNLOCK;
@@ -1557,6 +1577,10 @@ void *pvalue
if (INVALID_DB_REQ(type))
return ECA_BADTYPE;
if(!chix->ar.read_access){
return ECA_NORDACCESS;
}
if (count > chix->count)
return ECA_BADCOUNT;
@@ -1633,6 +1657,9 @@ int ca_array_get_callback
if (count > chix->count)
return ECA_BADCOUNT;
if(!chix->ar.read_access){
return ECA_NORDACCESS;
}
#ifdef vxWorks
if (!chix->piiu) {
@@ -1768,6 +1795,10 @@ void *usrarg;
if(INVALID_DB_FIELD(type))
return ECA_BADTYPE;
if(!chix->ar.write_access){
return ECA_NOWTACCESS;
}
/*
* check for valid count
*/
@@ -2054,6 +2085,10 @@ void *pvalue;
if(INVALID_DB_FIELD(type))
return ECA_BADTYPE;
if(!chix->ar.write_access){
return ECA_NOWTACCESS;
}
/*
* check for valid count
*/
+9 -1
View File
@@ -210,6 +210,10 @@ char *pname;
NULL,
CONN_ROUTINE,
NULL), NULL);
#if 0
status = ca_replace_access_rights_event(chix1, ar_event);
SEVCHK(status,NULL);
#endif
status = ca_pend_io(1000.0);
SEVCHK(status, NULL);
@@ -238,6 +242,10 @@ char *pname;
lib$init_timer();
#endif /*VMS*/
printf("Read Access=%d Write Access=%d\n",
ca_read_access(chix1),
ca_write_access(chix1));
/*
* verify we dont jam up on many uninterrupted
* solicitations
@@ -453,7 +461,7 @@ char *pname;
assert(conn_get_cb_count == 3);
printf("-- Put/Gets done- waiting for Events --\n");
status = ca_pend_event(2000.0);
status = ca_pend_event(10.0);
if (status == ECA_TIMEOUT) {
free(ptr);
+8 -7
View File
@@ -1425,9 +1425,10 @@ struct ioc_in_use *piiu;
chix->count = 0;
chix->state = cs_prev_conn;
chix->id.sid = ~0L;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
}
/*
* remove IOC from the hash table
*/
@@ -1460,18 +1461,18 @@ struct ioc_in_use *piiu;
chix = (chid) &piiu->chidlist.node.next;
while(chix = (chid) chix->node.next){
LOCKEVENTS;
if(chix->access_rights_func){
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->access_rights_func)(args);
}
if(chix->connection_func){
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->connection_func)(args);
}
if(chix->access_rights_func){
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->access_rights_func)(args);
}
UNLOCKEVENTS;
chix->piiu = piiuCast;
}
+9
View File
@@ -59,6 +59,7 @@ static char *iocmsghSccsId = "$Id$ CA version 4.1";
#define IOC_WRITE_NOTIFY 19 /* notify after write chan value */
#define IOC_CLIENT_NAME 20 /* CA V4.1 identify client */
#define IOC_HOST_NAME 21 /* CA V4.1 identify client */
#define IOC_ACCESS_RIGHTS 22 /* CA V4.1 asynch access rights chg */
/*
* for use with build and search and not_found (if search fails and
@@ -79,6 +80,14 @@ static char *iocmsghSccsId = "$Id$ CA version 4.1";
#define BI_ROUND(A) ((((unsigned long)A)+1)>>1)
#define BI_SIZEOF(A) (BI_ROUND(sizeof(A)))
/*
* For communicating access rights to the clients
*
* (placed in m_available hdr field of IOC_ACCESS_RIGHTS cmmd
*/
#define CA_ACCESS_RIGHT_READ (1<<0)
#define CA_ACCESS_RIGHT_WRITE (1<<1)
/*
* Required Message Alignment
*
+1 -1
View File
@@ -112,7 +112,7 @@ static char *os_depenhSccsId = "$Id$";
#endif /*VMS*/
#ifndef CA_OS_CONFIGURED
/* # error Please define one of vxWorks, UNIX or VMS */
@@@@@@ Please define one of vxWorks, UNIX or VMS @@@@@@
#endif
#ifndef NULL
+54
View File
@@ -648,6 +648,29 @@ struct in_addr *pnet_addr;
UNLOCKEVENTS;
break;
}
case IOC_ACCESS_RIGHTS:
{
int ar;
chid chan;
LOCK;
chan = bucketLookupItem(pBucket, piiu->curMsg.m_cid);
UNLOCK;
assert(chan);
ar = ntohl(piiu->curMsg.m_available);
chan->ar.read_access = (ar&CA_ACCESS_RIGHT_READ)?1:0;
chan->ar.write_access = (ar&CA_ACCESS_RIGHT_WRITE)?1:0;
if (chan->access_rights_func) {
struct access_rights_handler_args args;
args.chid = chan;
args.ar = chan->ar;
(*chan->access_rights_func) (args);
}
break;
}
default:
ca_printf("CAC: post_msg(): Corrupt cmd in msg %x\n",
piiu->curMsg.m_cmmd);
@@ -683,6 +706,7 @@ struct in_addr *pnet_addr;
IIU *allocpiiu;
IIU *chpiiu;
unsigned short *pMinorVersion;
int v41;
/*
* ignore broadcast replies for deleted channels
@@ -758,6 +782,18 @@ struct in_addr *pnet_addr;
chan->count = piiu->curMsg.m_count;
chan->id.sid = piiu->curMsg.m_cid;
/*
* Assume that we have access once connected briefly
* until the server is able to tell us the correct
* state for backwards compatibility.
*
* Their access rights call back does not get
* called for the first time until the information
* arrives however.
*/
chan->ar.read_access = TRUE;
chan->ar.write_access = TRUE;
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
@@ -771,6 +807,10 @@ struct in_addr *pnet_addr;
allocpiiu->minor_version_number = CA_UKN_MINOR_VERSION;
}
v41 = CA_V41(
CA_PROTOCOL_VERSION,
allocpiiu->minor_version_number);
if(chpiiu != allocpiiu){
/*
@@ -850,6 +890,20 @@ struct in_addr *pnet_addr;
CLRPENDRECV(TRUE);
}
/*
* if less than v4.1 then the server will never
* send access rights so we know that there
* will always be access and call their call back
* here
*/
if (chan->access_rights_func && !v41) {
struct access_rights_handler_args args;
args.chid = chan;
args.ar = chan->ar;
(*chan->access_rights_func) (args);
}
UNLOCK;
}
+313 -122
View File
@@ -164,6 +164,11 @@ ASCLIENTPVT ascpvt,
asClientStatus type
);
LOCAL void no_read_access_event(
struct client *client,
struct event_ext *pevext
);
LOCAL unsigned long bucketID;
@@ -255,10 +260,11 @@ struct message_buffer *recv
break;
}
evext.mp = mp;
evext.msg = *mp;
evext.pciu = pciu;
evext.send_lock = TRUE;
evext.get = TRUE;
evext.pdbev = NULL;
evext.size = dbr_size_n(mp->m_type, mp->m_count);
/*
@@ -569,7 +575,9 @@ struct client *client
&prsrv_cast_client->addrq,
&pciu->node);
UNLOCK_CLIENT(prsrv_cast_client);
pciu->client = client;
LOCK_CLIENT(client);
ellAdd(&client->addrq, &pciu->node);
UNLOCK_CLIENT(client);
@@ -582,6 +590,13 @@ struct client *client
*/
pciu->client->minor_version_number = mp->m_available;
/*
* register for asynch updates of access rights changes
* (only after the lock is released, we are added to
* the correct client, and the clients version is
* known)
*/
asRegisterClientCallback(pciu->asClientPVT, casAccessRightsCB);
}
@@ -935,21 +950,36 @@ struct client *client
}
memset(pevext,0,size);
pevext->msg = *mp;
pevext->mp = &pevext->msg; /* for speed- see
* IOC_READ */
pevext->pciu = pciu;
pevext->send_lock = TRUE;
pevext->size = dbr_size_n(mp->m_type, mp->m_count);
pevext->mask = ((struct monops *) mp)->m_info.m_mask;
pevext->get = FALSE;
LOCK_CLIENT(client);
ellAdd( &pciu->eventq, &pevext->node);
UNLOCK_CLIENT(client);
/*
* dont set up the event if no read access
*/
if(!asCheckGet(pciu->asClientPVT)){
pevext->pdbev = NULL;
no_read_access_event(client, pevext);
return;
}
pevext->pdbev = (struct event_block *)(pevext+1);
status = db_add_event(
client->evuser,
&pciu->addr,
read_reply,
pevext,
(unsigned) ((struct monops *) mp)->m_info.m_mask,
(struct event_block *)(pevext+1));
pevext->mask,
pevext->pdbev);
if (status == ERROR) {
pevext->pdbev = NULL;
LOCK_CLIENT(client);
send_err(
mp,
@@ -957,21 +987,9 @@ struct client *client
client,
RECORD_NAME(&pciu->addr));
UNLOCK_CLIENT(client);
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd(&rsrv_free_eventq, &pevext->node);
FASTUNLOCK(&rsrv_free_eventq_lck);
return;
}
/*
* Only add to the list if we can get enough
* memory. If not, attempts to delete it
* from the client will cause a warning message
* to be printed since it will not be found on
* the list.
*/
ellAdd( &pciu->eventq, &pevext->node);
/*
* always send it once at event add
*/
@@ -998,7 +1016,7 @@ struct client *client
* messages sent by the server).
*/
db_post_single_event((struct event_block *)(pevext+1));
db_post_single_event(pevext->pdbev);
return;
}
@@ -1016,10 +1034,10 @@ struct extmsg *mp,
struct client *client
)
{
FAST struct extmsg *reply;
FAST struct event_ext *pevext;
struct extmsg *reply;
struct event_ext *pevext;
struct channel_in_use *pciu;
FAST int status;
int status;
/*
*
@@ -1041,11 +1059,18 @@ struct client *client
}
}
while (pevext = (struct event_ext *) ellGet(&pciu->eventq)) {
while (TRUE){
LOCK_CLIENT(client);
pevext = (struct event_ext *) ellGet(&pciu->eventq);
UNLOCK_CLIENT(client);
status = db_cancel_event((struct event_block *)(pevext+1));
if (status){
taskSuspend(0);
if(!pevext){
break;
}
if(pevext->pdbev){
status = db_cancel_event(pevext->pdbev);
assert(status == OK);
}
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd(&rsrv_free_eventq, &pevext->node);
@@ -1111,11 +1136,10 @@ struct extmsg *mp,
struct client *client
)
{
struct extmsg *reply;
struct event_ext *pevext;
ELLLIST *peventq;
int status;
struct channel_in_use *pciu;
struct channel_in_use *pciu;
struct extmsg *reply;
struct event_ext *pevext;
int status;
/*
*
@@ -1127,46 +1151,60 @@ struct client *client
logBadId(client, mp);
return;
}
peventq = &pciu->eventq;
for (pevext = (struct event_ext *) peventq->node.next;
pevext;
pevext = (struct event_ext *) pevext->node.next)
if (pevext->msg.m_available == mp->m_available) {
status = db_cancel_event((struct event_block *)(pevext+1));
if (status == ERROR)
taskSuspend(0);
ellDelete(peventq, &pevext->node);
/*
* send delete confirmed message
*/
LOCK_CLIENT(client);
reply = (struct extmsg *) ALLOC_MSG(client, 0);
if (!reply) {
UNLOCK_CLIENT(client);
taskSuspend(0);
}
*reply = pevext->msg;
reply->m_postsize = 0;
END_MSG(client);
UNLOCK_CLIENT(client);
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd(&rsrv_free_eventq, &pevext->node);
FASTUNLOCK(&rsrv_free_eventq_lck);
return;
}
/*
* Not Found- return an error message
* search events on this channel for a match
* (there are usually very few monitors per channel)
*/
LOCK_CLIENT(client);
send_err(mp, ECA_BADMONID, client, RECORD_NAME(&pciu->addr));
for (pevext = (struct event_ext *) ellFirst(&pciu->eventq);
pevext;
pevext = (struct event_ext *) ellNext(&pevext->node)){
if (pevext->msg.m_available == mp->m_available) {
ellDelete(&pciu->eventq, &pevext->node);
break;
}
}
UNLOCK_CLIENT(client);
return;
/*
* Not Found- return an exception event
*/
if(!pevext){
LOCK_CLIENT(client);
send_err(mp, ECA_BADMONID, client, RECORD_NAME(&pciu->addr));
UNLOCK_CLIENT(client);
return;
}
/*
* cancel monitor activity in progress
*/
if(pevext->pdbev){
status = db_cancel_event(pevext->pdbev);
assert(status == OK);
}
/*
* send delete confirmed message
*/
LOCK_CLIENT(client);
reply = (struct extmsg *) ALLOC_MSG(client, 0);
if (!reply) {
UNLOCK_CLIENT(client);
assert(0);
}
*reply = pevext->msg;
reply->m_postsize = 0;
END_MSG(client);
UNLOCK_CLIENT(client);
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd(&rsrv_free_eventq, &pevext->node);
FASTUNLOCK(&rsrv_free_eventq_lck);
}
@@ -1185,7 +1223,6 @@ db_field_log *pfl
)
{
struct event_ext *pevext = pArg;
struct extmsg *mp = pevext->mp;
struct client *client = pevext->pciu->client;
struct channel_in_use *pciu = pevext->pciu;
struct extmsg *reply;
@@ -1206,18 +1243,18 @@ db_field_log *pfl
reply = (struct extmsg *) ALLOC_MSG(client, pevext->size);
if (!reply) {
send_err(mp, ECA_TOLARGE, client, RECORD_NAME(paddr));
send_err(&pevext->msg, ECA_TOLARGE, client, RECORD_NAME(paddr));
if (!eventsRemaining)
cas_send_msg(client,!pevext->send_lock);
if (pevext->send_lock)
UNLOCK_CLIENT(client);
if (!eventsRemaining)
cas_send_msg(client,FALSE);
return;
}
/*
* setup response message
*/
*reply = *mp;
*reply = pevext->msg;
reply->m_postsize = pevext->size;
reply->m_cid = (unsigned long)pciu->cid;
@@ -1226,52 +1263,37 @@ db_field_log *pfl
*/
v41 = CA_V41(CA_PROTOCOL_VERSION,client->minor_version_number);
if(!asCheckGet(pciu->asClientPVT)){
if(v41){
status = ECA_NORDACCESS;
}
else{
status = ECA_GETFAIL;
}
/*
* I cant wait to redesign this protocol from scratch!
*/
if(!v41||reply->m_cmmd==IOC_READ||reply->m_cmmd==IOC_READ_BUILD){
if(reply->m_cmmd==IOC_READ||
reply->m_cmmd==IOC_READ_BUILD){
if(v41){
status = ECA_NORDACCESS;
}
else{
status = ECA_GETFAIL;
}
/*
* old client & plain get & search/get
* continue to return an exception
* on failure
*/
send_err(mp, status, client, RECORD_NAME(paddr));
send_err(&pevext->msg, status,
client, RECORD_NAME(paddr));
}
else{
/*
* New clients recv the status of the
* operation directly to the
* event/put/get callback.
*
* Fetched value is zerod in case they
* use it even when the status indicates
* failure.
*
* The m_cid field in the protocol
* header is abused to carry the status
*/
bzero((char *)(reply+1), pevext->size);
reply->m_cid = status;
END_MSG(client);
no_read_access_event(client, pevext);
}
if (pevext->send_lock)
UNLOCK_CLIENT(client);
if (!eventsRemaining)
cas_send_msg(client,FALSE);
cas_send_msg(client,!pevext->send_lock);
if (pevext->send_lock){
UNLOCK_CLIENT(client);
}
return;
}
status = db_get_field(
paddr,
mp->m_type,
pevext->msg.m_type,
reply + 1,
mp->m_count,
pevext->msg.m_count,
pfl);
if (status < 0) {
/*
@@ -1283,8 +1305,8 @@ db_field_log *pfl
* continue to return an exception
* on failure
*/
send_err(mp, ECA_GETFAIL, client, RECORD_NAME(paddr));
log_header(mp, 0);
send_err(&pevext->msg, ECA_GETFAIL, client, RECORD_NAME(paddr));
log_header(&pevext->msg, 0);
}
else{
/*
@@ -1326,7 +1348,8 @@ db_field_log *pfl
* force string message size to be the true size rounded to even
* boundary
*/
if (mp->m_type == DBR_STRING && mp->m_count == 1) {
if (pevext->msg.m_type == DBR_STRING
&& pevext->msg.m_count == 1) {
/* add 1 so that the string terminator will be shipped */
strcnt = strlen((char *)(reply + 1)) + 1;
reply->m_postsize = strcnt;
@@ -1340,7 +1363,7 @@ db_field_log *pfl
* them up like db requests when the OPI does not keep up.
*/
if (!eventsRemaining)
cas_send_msg(client,FALSE);
cas_send_msg(client,!pevext->send_lock);
if (pevext->send_lock)
UNLOCK_CLIENT(client);
@@ -1348,6 +1371,66 @@ db_field_log *pfl
return;
}
/*
* no_read_access_event()
*
* !! LOCK needs to applied by caller !!
*
* substantial complication introduced here by the need for backwards
* compatibility
*/
LOCAL void no_read_access_event(
struct client *client,
struct event_ext *pevext
)
{
struct extmsg *reply;
int v41;
v41 = CA_V41(CA_PROTOCOL_VERSION,client->minor_version_number);
/*
* continue to return an exception
* on failure to pre v41 clients
*/
if(!v41){
send_err(
&pevext->msg,
ECA_GETFAIL,
client,
RECORD_NAME(&pevext->pciu->addr));
return;
}
reply = (struct extmsg *) ALLOC_MSG(client, pevext->size);
if (!reply) {
send_err(
&pevext->msg,
ECA_TOLARGE,
client,
RECORD_NAME(&pevext->pciu->addr));
return;
}
else{
/*
* New clients recv the status of the
* operation directly to the
* event/put/get callback.
*
* Fetched value is zerod in case they
* use it even when the status indicates
* failure.
*
* The m_cid field in the protocol
* header is abused to carry the status
*/
bzero((char *)(reply+1), pevext->size);
reply->m_cid = ECA_NORDACCESS;
END_MSG(client);
}
}
/*
*
@@ -1388,7 +1471,6 @@ struct extmsg *mp,
struct client *client
)
{
ELLLIST *addrq = &client->addrq;
struct extmsg *search_reply;
struct extmsg *get_reply;
unsigned short *pMinorVersion;
@@ -1454,10 +1536,29 @@ struct client *client
LOCK_CLIENT(client);
send_err(mp, ECA_ALLOCMEM, client, "No room for security table");
UNLOCK_CLIENT(client);
free(pchannel);
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return;
}
asPutClientPvt(pchannel->asClientPVT, pchannel);
/*
* Existing build() interface to the client does not provide mechanism
* to inform them that the channel connected but the value
* couldnt be fetched so search/get combined op
* to no read access channel not allowed.
*/
if (mp->m_cmmd == IOC_BUILD && !asCheckGet(pchannel->asClientPVT)) {
LOCK_CLIENT(client);
send_err(mp, ECA_NORDACCESS, client, RECORD_NAME(&tmp_addr));
UNLOCK_CLIENT(client);
asRemoveClient(&pchannel->asClientPVT);
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return;
}
asRegisterClientCallback(pchannel->asClientPVT, casAccessRightsCB);
/*
* allocate a server id and enter the channel pointer
@@ -1473,7 +1574,9 @@ struct client *client
send_err(mp, ECA_ALLOCMEM, client, "No room for hash table");
UNLOCK_CLIENT(client);
asRemoveClient(&pchannel->asClientPVT);
free(pchannel);
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return;
}
@@ -1485,9 +1588,9 @@ struct client *client
if (mp->m_cmmd == IOC_BUILD) {
FAST short type = (mp + 1)->m_type;
FAST unsigned int count = (mp + 1)->m_count;
FAST unsigned int size;
short type = (mp + 1)->m_type;
unsigned int count = (mp + 1)->m_count;
unsigned int size;
/*
* must be large enough to hold both the search and the build-get
@@ -1511,16 +1614,24 @@ struct client *client
pchannel->sid,
pchannel);
FASTUNLOCK(&rsrv_free_addrq_lck);
free(pchannel);
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pchannel->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
return;
} else {
struct event_ext evext;
evext.mp = mp + 1;
evext.pciu = pchannel;
evext.mp->m_cid = sid;
evext.msg = *(mp+1);
/*
* this allows extra build replies
* to be dicarded
*/
evext.msg.m_cmmd = IOC_READ_BUILD;
evext.msg.m_cid = sid;
evext.send_lock = FALSE;
evext.size = dbr_size_n(type, count);
evext.pdbev = NULL;
evext.get = TRUE;
/*
@@ -1531,12 +1642,6 @@ struct client *client
* is not flushed once each call.
*/
read_reply(&evext, &tmp_addr, TRUE, NULL);
/*
* this allows extra build replies
* to be dicarded
*/
get_reply->m_cmmd = IOC_READ_BUILD;
}
}
search_reply = (struct extmsg *)
@@ -1563,7 +1668,7 @@ struct client *client
END_MSG(client);
/* store the addr block on the cast queue until it is claimed */
ellAdd(addrq, &pchannel->node);
ellAdd(&client->addrq, &pchannel->node);
UNLOCK_CLIENT(client);
@@ -1781,13 +1886,99 @@ LOCAL struct channel_in_use *MPTOPCIU(struct extmsg *mp)
/*
* casAccessRightsCB()
*
* If access right state changes then inform the client.
*
*/
LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type)
{
struct client *pclient;
struct channel_in_use *pciu;
struct extmsg *reply;
struct event_ext *pevext;
int status;
unsigned ar;
int v41;
pciu = asGetClientPvt(ascpvt);
if(!pciu){
printf("casAccessRightsCB() without channel pointer ??\n");
return;
}
pclient = pciu->client;
assert(pclient);
v41 = CA_V41(CA_PROTOCOL_VERSION,pclient->minor_version_number);
switch(type)
{
case asClientCOAR:
/*
* noop if this is an old client
*/
if(!v41){
break;
}
ar = 0; /* none */
if(asCheckGet(ascpvt)){
ar |= CA_ACCESS_RIGHT_READ;
}
if(asCheckPut(ascpvt)){
ar |= CA_ACCESS_RIGHT_WRITE;
}
LOCK_CLIENT(pclient);
reply = (struct extmsg *)ALLOC_MSG(pclient, 0);
assert(reply);
*reply = nill_msg;
reply->m_cmmd = IOC_ACCESS_RIGHTS;
reply->m_cid = pciu->cid;
reply->m_available = ar;
END_MSG(pclient);
/*
* Update all event call backs
*/
for (pevext = (struct event_ext *) ellFirst(&pciu->eventq);
pevext;
pevext = (struct event_ext *) ellNext(&pevext->node)){
if(pevext->pdbev && !(ar&CA_ACCESS_RIGHT_READ)){
status = db_cancel_event(pevext->pdbev);
assert(status == OK);
pevext->pdbev = NULL;
}
else if(!pevext->pdbev && ar&CA_ACCESS_RIGHT_READ){
pevext->pdbev =
(struct event_block *)(pevext+1);
status = db_add_event(
pclient->evuser,
&pciu->addr,
read_reply,
pevext,
pevext->mask,
pevext->pdbev);
if (status == ERROR) {
pevext->pdbev = NULL;
send_err(
&pevext->msg,
ECA_ADDFAIL,
pclient,
RECORD_NAME(&pciu->addr));
}
}
if(pevext->pdbev){
db_post_single_event(pevext->pdbev);
}
}
UNLOCK_CLIENT(pclient);
break;
default:
break;
}
+48 -21
View File
@@ -45,23 +45,24 @@
*/
static char *sccsId = "$Id$";
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <vxWorks.h>
#include <ellLib.h>
#include <taskLib.h>
#include <types.h>
#include <sockLib.h>
#include <socket.h>
#include <in.h>
#include <unistd.h>
#include <logLib.h>
#include <string.h>
#include <usrLib.h>
#include <errnoLib.h>
#include <stdio.h>
#include <tickLib.h>
#include <sysLib.h>
#include <ellLib.h>
#include <taskwd.h>
#include <db_access.h>
#include <task_params.h>
@@ -272,8 +273,14 @@ LOCAL int terminate_one_client(struct client *client)
}
}
pciu = (struct channel_in_use *) & client->addrq;
while (pciu = (struct channel_in_use *) pciu->node.next){
while(TRUE){
LOCK_CLIENT(client);
pciu = (struct channel_in_use *) ellGet(&client->addrq);
UNLOCK_CLIENT(client);
if(!pciu){
break;
}
/*
* put notify in progress needs to be deleted
*/
@@ -283,19 +290,27 @@ LOCAL int terminate_one_client(struct client *client)
}
}
while (pevext = (struct event_ext *) ellGet(&pciu->eventq)) {
while (TRUE){
/*
* AS state change could be using this list
*/
LOCK_CLIENT(client);
pevext = (struct event_ext *) ellGet(&pciu->eventq);
UNLOCK_CLIENT(client);
if(!pevext){
break;
}
status = db_cancel_event(
(struct event_block *)(pevext + 1));
if (status)
taskSuspend(0);
if(pevext->pdbev){
status = db_cancel_event(pevext->pdbev);
assert(status == OK);
}
FASTLOCK(&rsrv_free_eventq_lck);
ellAdd(&rsrv_free_eventq, &pevext->node);
FASTUNLOCK(&rsrv_free_eventq_lck);
}
status = db_flush_extra_labor_event(client->evuser);
if (status)
taskSuspend(0);
assert(status==OK);
if(pciu->pPutNotify){
free(pciu->pPutNotify);
}
@@ -322,6 +337,14 @@ LOCAL int terminate_one_client(struct client *client)
NULL,
NULL);
}
/*
* place per channel block onto the
* free list
*/
FASTLOCK(&rsrv_free_addrq_lck);
ellAdd(&rsrv_free_addrq, &pciu->node);
FASTUNLOCK(&rsrv_free_addrq_lck);
}
if (client->evuser) {
@@ -338,13 +361,6 @@ LOCAL int terminate_one_client(struct client *client)
NULL,
NULL);
/* free dbaddr str */
FASTLOCK(&rsrv_free_addrq_lck);
ellConcat(
&rsrv_free_addrq,
&client->addrq);
FASTUNLOCK(&rsrv_free_addrq_lck);
if(FASTLOCKFREE(&client->putNotifyLock)<0){
logMsg("CAS: couldnt free sem\n",
NULL,
@@ -448,6 +464,7 @@ int client_stat(void)
*/
LOCAL void log_one_client(struct client *client)
{
int i;
struct channel_in_use *pciu;
struct sockaddr_in *psaddr;
char *pproto;
@@ -487,6 +504,7 @@ LOCAL void log_one_client(struct client *client)
bytes_reserved = 0;
bytes_reserved += sizeof(struct client);
LOCK_CLIENT(client);
pciu = (struct channel_in_use *) client->addrq.node.next;
while (pciu){
bytes_reserved += sizeof(struct channel_in_use);
@@ -499,6 +517,7 @@ LOCAL void log_one_client(struct client *client)
}
pciu = (struct channel_in_use *) ellNext(&pciu->node);
}
UNLOCK_CLIENT(client);
psaddr = &client->addr;
printf("\tRemote address %u.%u.%u.%u Remote port %d state=%s\n",
@@ -511,13 +530,21 @@ LOCAL void log_one_client(struct client *client)
printf( "\tChannel count %d\n", ellCount(&client->addrq));
printf( "\t%d bytes allocated\n", bytes_reserved);
LOCK_CLIENT(client);
pciu = (struct channel_in_use *) client->addrq.node.next;
i=0;
while (pciu){
printf( "\t%s(%d) ",
printf( "\t%s(%d%c%c)",
pciu->addr.precord,
pciu->eventq.count);
ellCount(&pciu->eventq),
asCheckGet(pciu->asClientPVT)?'r':'-',
asCheckPut(pciu->asClientPVT)?'w':'-');
pciu = (struct channel_in_use *) ellNext(&pciu->node);
if( ++i % 3 == 0){
printf("\n");
}
}
UNLOCK_CLIENT(client);
printf("\n");
+7 -6
View File
@@ -56,7 +56,7 @@
* pend which could lock up the cast server.
*/
static char *sccsId = "@(#)cast_server.c 1.17\t8/5/93";
static char *sccsId = "$Id$";
#include <vxWorks.h>
#include <ellLib.h>
@@ -253,7 +253,7 @@ int cast_server(void)
}
if(CASDEBUG>2)
count = prsrv_cast_client->addrq.count;
count = ellCount(&prsrv_cast_client->addrq);
status = camessage(
prsrv_cast_client,
@@ -273,11 +273,12 @@ int cast_server(void)
}
}
if(prsrv_cast_client->addrq.count){
if(CASDEBUG>2){
if(CASDEBUG>2){
if(ellCount(&prsrv_cast_client->addrq)){
logMsg( "CAS: Fnd %d name matches (%d tot)\n",
prsrv_cast_client->addrq.count-count,
prsrv_cast_client->addrq.count,
ellCount(&prsrv_cast_client->addrq)
-count,
ellCount(&prsrv_cast_client->addrq),
NULL,
NULL,
NULL,
+10 -5
View File
@@ -125,9 +125,10 @@ struct channel_in_use{
struct event_ext{
ELLNODE node;
struct extmsg msg;
struct extmsg *mp; /* for speed (IOC_READ) */
struct channel_in_use *pciu;
struct event_block *pdbev; /* ptr to db event block */
unsigned size; /* for speed */
unsigned mask;
char modified; /* mod & ev flw ctrl enbl */
char send_lock; /* lock send buffer */
char get; /* T: get F: monitor */
@@ -157,10 +158,14 @@ GLBLTYPE struct client *prsrv_cast_client;
GLBLTYPE BUCKET *pCaBucket;
#define LOCK_CLIENT(CLIENT)\
FASTLOCK(&(CLIENT)->lock);
{\
FASTLOCK(&(CLIENT)->lock);\
}
#define UNLOCK_CLIENT(CLIENT)\
FASTUNLOCK(&(CLIENT)->lock);
{ \
FASTUNLOCK(&(CLIENT)->lock);\
}
#define EXTMSGPTR(CLIENT)\
((struct extmsg *) &(CLIENT)->send.buf[(CLIENT)->send.stk])
@@ -177,9 +182,9 @@ FASTUNLOCK(&(CLIENT)->lock);
(CLIENT)->send.stk += sizeof(struct extmsg) + EXTMSGPTR(CLIENT)->m_postsize
#define LOCK_CLIENTQ FASTLOCK(&clientQlock)
#define LOCK_CLIENTQ FASTLOCK(&clientQlock);
#define UNLOCK_CLIENTQ FASTUNLOCK(&clientQlock)
#define UNLOCK_CLIENTQ FASTUNLOCK(&clientQlock);
struct client *existing_client();
int camsgtask();