📄 distnamelib.c
字号:
}#else distNameRmtAdd (DIST_IF_BROADCAST_ADDR, name, nameLen, value, valueLen, type);#endif return (OK); /* return OK, always */ }/***************************************************************************** distNameLclAdd - bind name to value in local name database (VxFusion option)** This routine binds a name to a given value in name database. If <type>* is a distributed object preprocess and postprocess identifier.** NOTE: Before calling distNameLclAdd(), nameLen and valueLen* must been tested to prevent overflows.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if successful.** NOMANUAL*/LOCAL STATUS distNameLclAdd ( char * name, /* name to enter in database */ int nameLen, /* strlen (name) */ void * value, /* value associated with name */ int valueLen, /* size of value in bytes */ DIST_NAME_TYPE type /* type associated with name */ ) { DIST_NAME_DB_NODE * pDbNode; DIST_OBJ_NODE * pObjNode; void * pVal; MSG_Q_ID msgQId; /* Preprocessing */ switch (type) { case T_DIST_MSG_Q: { /* * A little tricky, what we do here: user gives us a * message queue id. Check if it is a distributed * message id. If not, return ERROR. * Create a new DIST_OBJ_NODE and copy distributed * id to new DIST_OBJ_NODE. Return the new MSG_Q_ID * (which is in fact another reference to the MSG_Q_ID, * the user gave us). */ msgQId = *((MSG_Q_ID *) value); if (!ID_IS_DISTRIBUTED (msgQId)) return (ERROR); /* not a distributed message queue */ if (DIST_OBJ_VERIFY (msgQId) == ERROR) return (ERROR); pObjNode = MSG_Q_ID_TO_DIST_OBJ_NODE (msgQId); if (! IS_DIST_MSG_Q_OBJ (pObjNode)) return (ERROR); /* legal object id, but not a message queue */ pVal = &(pObjNode->objNodeUniqId); valueLen = sizeof (pObjNode->objNodeUniqId); break; } default: pVal = value; } /* Local database update (raw part). */ pDbNode = distNameLclAddRaw (name, nameLen, pVal, valueLen, type); if (pDbNode == NULL) return (ERROR); /* Postprocessing */ switch (type) { case T_DIST_MSG_Q: *((MSG_Q_ID *) value) = *((MSG_Q_ID *) &pDbNode->value); } return (OK); }/***************************************************************************** distNameBurst - burst out name database (VxFusion option)** This routine is used by INCO to update the remote name database on* node <nodeId>. All entries in the database are transmitted.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if successful.** NOMANUAL*/STATUS distNameBurst ( DIST_NODE_ID nodeId /* node receiving burst */ ) { DIST_NAME_BURST burst; burst.burstNodeId = nodeId; burst.burstStatus = OK; distNameEach ((FUNCPTR) distNameBurstOne, (int) &burst); return (burst.burstStatus); }/***************************************************************************** distNameBurstOne - burst out single name database entry (VxFusion option)** This routine bursts out a single database entry to a node.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: TRUE, if burst out successful** NOMANUAL*/LOCAL BOOL distNameBurstOne ( DIST_NAME_DB_NODE * pNode, /* node receiving burst */ DIST_NAME_BURST * pBurst /* the entry to send */ ) { char *name = (char *) &pNode->symName; if ((pBurst->burstStatus = distNameRmtAdd (pBurst->burstNodeId, name, strlen (name), &pNode->value, pNode->valueLen, pNode->type)) == ERROR) return (FALSE); return (TRUE); }/***************************************************************************** distNameRmtAdd - bind name to value in remote name databases (VxFusion option)** This routine adds or updates a name/value pair in a remote node.** NOTE: Before calling distNameRmtAdd(), nameLen and valueLen* must been tested to prevent overflows.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if successful.** NOMANUAL*/LOCAL STATUS distNameRmtAdd ( DIST_NODE_ID nodeId, /* node to address */ char * name, /* name to enter in database */ int nameLen, /* strlen (name) */ void * value, /* value associated with name */ int valueLen, /* size of value in bytes */ DIST_NAME_TYPE type /* type associated with name */ ) { DIST_NAME_TYPE_ALL valNet; DIST_PKT_DNDB_ADD pktDndbAdd; DIST_IOVEC IOVec[3]; STATUS status; void * pValNet; DIST_OBJ_UNIQ_ID * pObjUniqId; DIST_OBJ_NODE * pObjNode; MSG_Q_ID msgQId; /* * We have to copy data, since some processors allow * memory requests to non-aligned addresses, others * don't. */ switch (type) { case T_DIST_UINT8: { pValNet = value; break; } case T_DIST_UINT16: { bcopy (value, (char *) &(valNet.uint16), valueLen); valNet.uint16 = htons (valNet.uint16); pValNet = &(valNet.uint16); break; } case T_DIST_NODE: case T_DIST_FLOAT: case T_DIST_UINT32: { bcopy (value, (char *) &(valNet.uint32), valueLen); valNet.uint32 = htonl (valNet.uint32); pValNet = &valNet.uint32; break; } case T_DIST_UINT64: case T_DIST_DOUBLE: { bcopy (value, (char *) &(valNet.uint64), valueLen); pValNet = distHton64((uint32_t*)&(valNet.uint64),type); break; } case T_DIST_MSG_Q: /* complex objects go here */ { /* * A little tricky, what we do here: user gives us a * message queue id. Check if it is a distributed * message id. If not, return ERROR. * Get the distributed (unique!) id instead of the * local MSG_Q_ID (local pointer). */ msgQId = *((MSG_Q_ID *) value); if (!ID_IS_DISTRIBUTED (msgQId)) return (ERROR); /* not a distributed message queue */ if (DIST_OBJ_VERIFY (msgQId) == ERROR) return (ERROR); pObjNode = MSG_Q_ID_TO_DIST_OBJ_NODE (msgQId); if (! IS_DIST_MSG_Q_OBJ (pObjNode)) return (ERROR); /* legal object id, but not a message queue */ bcopy ((char *) &(pObjNode->objNodeUniqId), (char *) &(valNet.objUniqId), sizeof (pObjNode->objNodeUniqId)); pObjUniqId = (DIST_OBJ_UNIQ_ID *) &(valNet.objUniqId); pObjUniqId->objUniqReside = htonl (pObjUniqId->objUniqReside); pObjUniqId->objUniqId = htonl (pObjUniqId->objUniqId); pValNet = pObjUniqId; valueLen = sizeof (*pObjUniqId); break; } default: pValNet = value; /* user defined, do not know what to do */ } /* Remote database update. */ pktDndbAdd.dndbAddHdr.pktType = DIST_PKT_TYPE_DNDB; pktDndbAdd.dndbAddHdr.pktSubType = DIST_PKT_TYPE_DNDB_ADD; pktDndbAdd.dndbAddType = htons (type); pktDndbAdd.dndbAddValueLen = (UINT8) valueLen; pktDndbAdd.dndbAddNameLen = (UINT8) nameLen; IOVec[0].pIOBuffer = &pktDndbAdd; IOVec[0].IOLen = DIST_PKT_HDR_SIZEOF (DIST_PKT_DNDB_ADD); IOVec[1].pIOBuffer = pValNet; IOVec[1].IOLen = valueLen; IOVec[2].pIOBuffer = name; IOVec[2].IOLen = nameLen; status = distNetIOVSend (nodeId, &IOVec[0], 3, WAIT_FOREVER, DIST_PKT_DNDB_PRIO); return (status); }/***************************************************************************** distNameFind - find an object by name in the local database (VxFusion option)** This routine searches the distributed name database for an object matching* a specified <name>. If the object is found, a pointer to the value and its* type are copied to the address pointed to by <pValue> and <pType>.* If the type is T_DIST_MSG_Q, the identifier returned can be used with* generic message queue handling routines in msgQLib, such as msgQSend(), * msgQReceive(), and msgQNumMsgs().** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, or ERROR if the search fails.** ERRNO:* \is* \i S_distNameLib_NAME_TOO_LONG* The name to be found in the database is too long.* \i S_distNameLib_INVALID_WAIT_TYPE* The wait type should be either NO_WAIT or WAIT_FOREVER .* \ie*/STATUS distNameFind ( char * name, /* name to search for */ void ** pValue, /* where to return ptr to value */ DIST_NAME_TYPE * pType, /* where to return type */ int waitType /* NO_WAIT or WAIT_FOREVER */ ) { DIST_NAME_DB_NODE * pNode; DIST_NAME_DB_NODE matchNode; int nameLen; if ((nameLen = strlen (name)) > DIST_NAME_MAX_LENGTH) { errnoSet (S_distNameLib_NAME_TOO_LONG); return (ERROR); /* name too long */ } if (waitType != NO_WAIT && waitType != WAIT_FOREVER) { errnoSet (S_distNameLib_INVALID_WAIT_TYPE); return (ERROR); /* wait type is invalid */ } bcopy (name, (char *) &matchNode.symName, nameLen + 1);again: distNameLclLock(); pNode = (DIST_NAME_DB_NODE *) hashTblFind (distNameDbId, (HASH_NODE *)&matchNode, KEY_CMP_ARG); distNameLclUnlock(); if (!pNode) { if (waitType == WAIT_FOREVER) { /* object not found; we have to wait ... */ distNameLclBlockOnAdd(); goto again; } else return (ERROR); /* object not found */ } *pType = pNode->type; *pValue = &pNode->value; return (OK); }/***************************************************************************** distNameFindByValueAndType - look up the name of an object by value and type (VxFusion option)** This routine searches the distributed name database for an object matching* a specified <value> and <type>. If the object is found, its name is * copied to the address pointed to by <name>.** NOTE:* Unlike the smNameFindByValue() routine, used with the shared-memory * objects name database, this routine must know the type of the object* being searched for. Searching on the value only might not return a* unique object.* * AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, or ERROR if the search fails.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -