#include // ***************************************************************************** // * cdevMonitorNode::cdevMonitorEntry Static Variables. // ***************************************************************************** int cdevMonitorNode::cdevMonitorEntry::VALUE_TAG = 0; int cdevMonitorNode::cdevMonitorEntry::STATUS_TAG = 0; int cdevMonitorNode::cdevMonitorEntry::TIME_TAG = 0; int cdevMonitorNode::cdevMonitorEntry::DEVICE_TAG = 0; // ***************************************************************************** // * cdevMonitorData::cdevMonitorData: // * This is the default constructor. // ***************************************************************************** cdevMonitorData::cdevMonitorData ( void ) : criticalTags(NULL), criticalTagCnt(0), cdevData() { } // ***************************************************************************** // * cdevMonitorData::cdevMonitorData: // * This builds a cdevMonitorData from a cdevData. // ***************************************************************************** cdevMonitorData::cdevMonitorData ( const cdevData & data ) : criticalTags(NULL), criticalTagCnt(0), cdevData(data) { } // ***************************************************************************** // * cdevMonitorData::cdevMonitorData: // * This builds a cdevMonitorData from a cdevMonitorData. // ***************************************************************************** cdevMonitorData::cdevMonitorData ( const cdevMonitorData & data ) : criticalTags(data.criticalTags), criticalTagCnt(data.criticalTagCnt), cdevData(*(const cdevData *)&data) { } // ***************************************************************************** // * isTagCritical : // * This method will walk through the list of tags and attempt to find // * the caller specified tag. This method returns 1 if it is present, or // * 0 if it is not. // ***************************************************************************** int cdevMonitorData::isTagCritical ( int tag ) { for(int i=0; inext_) { // ***************************** // * Do not process entries * // * with CDEV_INVALID as the * // * dataType or 0 as the tag. * // ***************************** if(ptr->dataType_==CDEV_INVALID || ptr->tag_==0 || !isTagCritical(ptr->tag_)) continue; // ***************************** // * Calculate the number of * // * elements in this tagged * // * data item. * // ***************************** int numElements = ptr->dim_!=0?ptr->elems_:1; // ***************************** // * Increment the counter * // ***************************** cdevElementCnt++; // ***************************** // * Add the size of the * // * cdevDataEntries tag_, * // * dataType_, dim_, elems_. * // ***************************** xdrDataSize += 4 * XDR_Sizeof((int)1); // ***************************** // * Add the size of the * // * cdevBounds data. * // ***************************** xdrDataSize += ptr->dim_ * (XDR_Sizeof((int)1) * 2); // ***************************** // * Add the size of the data * // ***************************** if (ptr->dataType_==CDEV_BYTE) xdrDataSize += numElements * XDR_Sizeof((unsigned char)'c'); else if(ptr->dataType_==CDEV_INT16) xdrDataSize += numElements * XDR_Sizeof((short)1); else if(ptr->dataType_==CDEV_UINT16) xdrDataSize += numElements * XDR_Sizeof((unsigned short)1); else if(ptr->dataType_==CDEV_INT32) xdrDataSize += numElements * XDR_Sizeof((long)1); else if(ptr->dataType_==CDEV_UINT32) xdrDataSize += numElements * XDR_Sizeof((unsigned long)1); else if(ptr->dataType_==CDEV_FLOAT) xdrDataSize += numElements * XDR_Sizeof((float)1); else if(ptr->dataType_==CDEV_DOUBLE) xdrDataSize += numElements * XDR_Sizeof((double)1); else if(ptr->dataType_==CDEV_STRING) { if(numElements==1) xdrDataSize += XDR_Sizeof(ptr->data_.str); else for(i=0; idata_.strarr[i]); } else if(ptr->dataType_==CDEV_TIMESTAMP) xdrDataSize += numElements * XDR_Sizeof(ptr->data_.ts); } *elementCount = cdevElementCnt; *bufLen = xdrDataSize; return *bufLen>0?CDEV_SUCCESS:CDEV_ERROR; } // ***************************************************************************** // * xdrExport: // * This function encapsulates the contents of the cdevData class into a // * binary stream. This function allocates the buffer and returns the new // * buffer and the buffer size. // ***************************************************************************** int cdevMonitorData::xdrExport ( char ** buf, size_t * bufLen ) { size_t count = 0; // ************************************# // * Calculate the size of the buffer # // ************************************# xdrSize(bufLen, &count); // ************************************# // * Allocate the buffer and call the # // * export function. # // ************************************# if((*buf = new char[*bufLen])!=NULL) xdrExport(*buf, *bufLen, count); return buf==NULL?CDEV_ERROR:CDEV_SUCCESS; } // ***************************************************************************** // * xdrExport: // * This function encapsulates the contents of the cdevData class into a // * preallocated binary stream. The buf parameter contains the address of // * the caller allocated buffer, the bufLen parameter specifies the size // * of the buffer, and the count parameter specifies the number of tagged // * data items that will be copied from the cdevData object into the // * binary stream. // ***************************************************************************** int cdevMonitorData::xdrExport ( char * buf, size_t bufLen, size_t count ) { cdevDataEntry * ptr; XDR_Writer writer; int xdrDataSize = bufLen; int cdevElementCnt = count; int i; // ************************************# // * Allocate the buffer # // ************************************# writer.attachData(buf, bufLen); // ************************************# // * Transfer the data to the buffer # // ************************************# // ************************************* // * Write the number of elements * // ************************************* writer.put(cdevElementCnt); // ************************************* // * Write each valid item. * // ************************************* for(ptr = entries; ptr != NULL; ptr = ptr->next_) { // ***************************** // * Do not process entries * // * with CDEV_INVALID as the * // * dataType or 0 as the tag. * // ***************************** if(ptr->dataType_==CDEV_INVALID || ptr->tag_==0 || !isTagCritical(ptr->tag_)) continue; // ***************************** // * Calculate the number of * // * elements in this tagged * // * data item. * // ***************************** int numElements = ptr->dim_!=0?ptr->elems_:1; // ***************************** // * Decrement the counter * // ***************************** cdevElementCnt--; // ***************************** // * Write the tag_, dataType_ * // * dim_, and elems_ of the * // * cdevDataEntry object. * // ***************************** writer.put((int)ptr->tag_); writer.put((int)ptr->dataType_); writer.put((int)ptr->dim_); writer.put((int)ptr->elems_); // ***************************** // * Write the cdevBounds * // * values asssociated with * // * the cdevDataEntry (if any)* // ***************************** cdevBounds * bounds = ptr->bounds(); for(i=0; idim_; i++) { writer.put((int)bounds[i].offset); writer.put((int)bounds[i].length); } // ***************************** // * Write the data * // ***************************** if(ptr->dataType_==CDEV_BYTE) { if(numElements==1) writer.put(ptr->data_.cval); else for(i=0; idata_.cptr[i]); } else if(ptr->dataType_==CDEV_INT16) { if(numElements==1) writer.put(ptr->data_.sval); else for(i=0; idata_.sptr[i]); } else if(ptr->dataType_==CDEV_UINT16) { if(numElements==1) writer.put(ptr->data_.usval); else for(i=0; idata_.usptr[i]); } else if(ptr->dataType_==CDEV_INT32) { if(numElements==1) writer.put(ptr->data_.lval); else for(i=0; idata_.lptr[i]); } else if(ptr->dataType_==CDEV_UINT32) { if(numElements==1) writer.put(ptr->data_.ulval); else for(i=0; idata_.ulptr[i]); } else if(ptr->dataType_==CDEV_FLOAT) { if(numElements==1) writer.put(ptr->data_.fval); else for(i=0; idata_.fptr[i]); } else if(ptr->dataType_==CDEV_DOUBLE) { if(numElements==1) writer.put(ptr->data_.dval); else for(i=0; idata_.dptr[i]); } else if(ptr->dataType_==CDEV_STRING) { if(numElements==1) writer.put(ptr->data_.str); else for(i=0; idata_.strarr[i]); } else if(ptr->dataType_==CDEV_TIMESTAMP) { if(numElements==1) writer.put(ptr->data_.ts); } } // ************************************* // * Detach the data from the writer * // * object before the object is * // * destroyed. * // ************************************* writer.detachData(); return CDEV_SUCCESS; } // ***************************************************************************** // * cdevMonitorNode::cdevMonitorEntry::cdevMonitorEntry : // * This is the constructor for the cdevMonitorEntry class that is internal to the // * cdevMonitorNode class. // * // * This constructor will initialize all data items and will then populate // * the list of triggers with all properties from the context that are // * marked with 2 or 3. It will then populate the properties list with // * all properties from the context that have any value other than 0. // * // * If not properties are in the context, then the following settings will // * be used by default... // * value = 3 // * status = 1 // * time = 1 // * // * The cdevMessage object becomes the property of the cdevMonitorNode // * object and should not be accessed again by the caller. // * // * The deviceIdx indicates the specific device that is being monitored // * within a multi-device list. // ***************************************************************************** cdevMonitorNode::cdevMonitorEntry::cdevMonitorEntry( cdevMessage * Message, int DeviceIdx=0 ) : next(NULL), message(Message), triggers(NULL), trigType(NULL), trigCnt(0), properties(NULL), propCnt(0), deviceIdx(DeviceIdx) { // ********************************************************************* // * Populate the static variables if they have not already been set. // ********************************************************************* if(VALUE_TAG==0) { cdevData::tagC2I("value", &VALUE_TAG); cdevData::tagC2I("status", &STATUS_TAG); cdevData::tagC2I("time", &TIME_TAG); // ************************************************************* // * Added to support multi-device monitors. // ************************************************************* cdevData::tagC2I("device", &DEVICE_TAG); } if(message!=NULL) { int tag; size_t tagElems; int tagVal; // ************************************************************* // * Start by removing the cdevData data if it has been // * included. This component will not be necessary to process // * the monitors. // ************************************************************* message->setData(NULL); // ************************************************************* // * If the context has been specified, then read the context // * to determine the number of monitorable data items. // ************************************************************* if(message->getContext()!=NULL) { cdevData * context = message->getContext(); cdevDataIterator iter(context); iter.init(); while((tag=iter.tag())!=0) { tagElems = 0; tagVal = 0; context->getElems(tag, &tagElems); if(tagElems==1) { context->get(tag, &tagVal); if(tagVal>1) trigCnt++; if(tagVal>0) propCnt++; } ++iter; } // ***************************************************** // * If the number of monitorable data items is greater // * than 0, then allocate a sufficient buffer and copy // * the tag names and tag types into the buffer. // ***************************************************** if(trigCnt>0) { // ********************************************* // * Added to support multi-device list. // ********************************************* if(message->getDeviceCount()>1) propCnt++; iter.init(); triggers = new int[trigCnt+trigCnt+propCnt]; trigType = &triggers[trigCnt]; properties = &triggers[trigCnt+trigCnt]; trigCnt = 0; propCnt = 0; while((tag=iter.tag())!=0) { tagElems = 0; tagVal = 0; context->getElems(tag, &tagElems); if(tagElems==1) { context->get(tag, &tagVal); if(tagVal>1) { triggers[trigCnt] = tag; trigType[trigCnt++] = tagVal; } if(tagVal>0) properties[propCnt++] = tag; } ++iter; } // ********************************************* // * Added to support multi-device list. // ********************************************* if(message->getDeviceCount()>1) properties[propCnt++] = DEVICE_TAG; } } // ************************************************************* // * If not tags were specified or the context was blank... then // * use the default setup. // ************************************************************* if(trigCnt<=0) { trigCnt = 1; propCnt = 3; // ***************************************************** // * Added to support multi-device list. // ***************************************************** if(message->getDeviceCount()>1) propCnt++; triggers = new int[2+propCnt]; trigType = &triggers[1]; properties = &triggers[2]; triggers[0] = VALUE_TAG; trigType[0] = 3; properties[0] = VALUE_TAG; properties[1] = STATUS_TAG; properties[2] = TIME_TAG; // ***************************************************** // * Added to support multi-device list. // ***************************************************** if(message->getDeviceCount()>1) properties[3] = DEVICE_TAG; } } } // ***************************************************************************** // * cdevMonitorNode::cdevMonitorEntry::~cdevMonitorEntry : // * This is the destructor for the node object that is internal to the // * cdevMonitorNode class. It is responsible for deleteing the cdevMessage // * object and freeing any memory that was allocated to the triggers // * object. // * // * Note that this destructor will delete all of the nodes that are stored // * below this one in the list. // ****************************************************************************** cdevMonitorNode::cdevMonitorEntry::~cdevMonitorEntry ( void ) { if(message) delete message; if(triggers) delete triggers; if(next!=NULL) delete next; } // ***************************************************************************** // * cdevMonitorNode::cdevMonitorNode : // * This is the constructor for the cdevMonitorNode class. It will save a // * copy of the Parent variable and will use the user specified Device and // * Attrib to create the hashString. // ***************************************************************************** cdevMonitorNode::cdevMonitorNode ( cdevMonitorTable * Parent, char * Device, char * Attrib ) : parent(Parent), hashString(NULL), nodes(NULL) { hashString = new char[strlen(Device)+strlen(Attrib)+2]; sprintf(hashString, "%s %s", Device, Attrib); } // ***************************************************************************** // * cdevMonitorNode::~cdevMonitorNode : // * This is the destructor for the cdevMonitorNode object. It will delete // * the hashString and each node from the list of monitors. // ***************************************************************************** cdevMonitorNode::~cdevMonitorNode ( void ) { if(hashString) delete hashString; if(nodes) { // ************************************************************* // * Prior to deleteing itself, this class will first fire its // * monitors once more using a 1 in the endOfTransaction // * parameter in order to inform the client side that it will // * receive no further transactions. // ************************************************************* cdevMonitorEntry * node = nodes; while(node) { fireMonitor(node, -1, &mData, 1); node = node->next; } delete nodes; } } // ***************************************************************************** // * cdevMonitorNode::insertMonitor : // * This method is used to add a new monitor for the device / attribute // * pair associated with this object. // * // * The cdevData object that is provided in the cdevData object is the // * collection of all current property values for the device / attribute // * pair. This data will be used to automatically dispatch the first // * callback when the monitor is initially installed. // * // * The deviceIdx indicates the specific device that is being monitored // * within a multi-device list. // ***************************************************************************** int cdevMonitorNode::insertMonitor ( cdevMessage * request, cdevData * data, int deviceIdx = 0 ) { int result = 0; cdevMonitorEntry * node = new cdevMonitorEntry(request, deviceIdx); if(node->trigCnt > 0) { node->next = nodes; nodes = node; } else { delete node; result = -1; } if(data!=NULL) { mData = *data; fireMonitor(node, -1, &mData); } return result; } // ***************************************************************************** // * cdevMonitorNode::removeMonitor : // * This method is used to remove a specific monitor by submitting a // * cdevMessage that contains the transaction index to be canceled in the // * cancelTransIndex element. // ***************************************************************************** int cdevMonitorNode::removeMonitor ( cdevMessage * request ) { return request==NULL?-1:removeMonitor(request->getCancelTransIndex()); } // ***************************************************************************** // * cdevMonitorNode::removeMonitor : // * This method is used to remove a specific monitor by submitting a // * the transaction index to be canceled. // ***************************************************************************** int cdevMonitorNode::removeMonitor ( unsigned cancelTransIndex ) { int result = -1; cdevMonitorEntry * node = nodes, *prev = NULL; while(node!=NULL && node->message->getTransIndex() != cancelTransIndex) { prev = node; node = node->next; } if(node!=NULL) { if(prev==NULL) nodes = node->next; else prev->next = node->next; node->next = NULL; // ************************************************************* // * This code portion added to inform client side that the // * monitor is terminating. When a monitor returns an // * operationCode of 0 - it indicates that there will be no // * further data transmissions. // * // * The 1 provided in the endOfTransaction parameter indicates // * that this transaction is finished. // ************************************************************* fireMonitor(node, -1, &mData, 1); delete node; result = 0; } return result; } // ***************************************************************************** // * cdevMonitorNode::removeClientMonitors : // * This method is used to remove all nodes that are associated with a // * specified clientID. // ***************************************************************************** int cdevMonitorNode::removeClientMonitors ( short clientID, int fire ) { cdevMonitorEntry * node = nodes, *prev = NULL; while(node!=NULL) { if(node->message->getClientID() == clientID) { cdevMonitorEntry * nextcdevMonitorEntry = node->next; node->next = NULL; // ***************************************************** // * This code portion added to inform client side that // * the monitor is terminating. When a monitor returns // * an operationCode of 0 - it indicates that there // * will be no further data transmissions. // * // * The 1 provided in the endOfTransaction parameter // * indicates that this transaction is finished. // ***************************************************** if(fire) fireMonitor(node, -1, &mData, 1); delete node; if(prev==NULL) nodes = nextcdevMonitorEntry; else prev->next = nextcdevMonitorEntry; node = nextcdevMonitorEntry; } else { prev = node; node = node->next; } } return 0; } // ***************************************************************************** // * cdevMonitorNode::fireMonitor : // * This method is used to submit a change to a monitored property. If the // * value of property is NULL, then all of the trigger properties will be // * fired. // * // * Note that the data parameter should be populated with all of the // * properties that are associated with the particular device / attribute // * pair. // ***************************************************************************** int cdevMonitorNode::fireMonitor( char * property, cdevData * data ) { int tag = -1; if(property!=NULL) cdevData::tagC2I(property, &tag); return fireMonitor(tag, data); } // ***************************************************************************** // * cdevMonitorNode::fireMonitor : // * This method is used to submit a change to a monitored property. If the // * value of property is -1, then it will fire all monitors that are listed // * in the triggers parameter. // * // * Note that the data parameter should be populated with all of the // * properties that are associated with the particular device / attribute // * pair. // * // * This method will return 0 if any monitors were actually dispatched, // * otherwise it will return -1. // ***************************************************************************** int cdevMonitorNode::fireMonitor( int property, cdevData * data ) { int result = -1; cdevMonitorEntry * node = nodes; // ********************************************************************* // * Attach the data that is contained in the cdevData object to the // * cdevMonitorData object. // ********************************************************************* if(data!=NULL) { // ************************************************************* // * Note here I am copying the contents of the user provided // * data to the mData structure that is local to the // * cdevMonitorNode. // ************************************************************* mData = *data; while(node!=NULL) { if(fireMonitor(node, property, &mData)==0) result = 0; node = node->next; } } return result; } // ***************************************************************************** // * cdevMonitorNode::fireMonitor : // * This method is used to submit a change to a monitored property. If the // * value of property is -1, then it will fire all monitors that are listed // * in the triggers parameter. // * // * The endOfTransaction flag indicates that this is the last monitor that // * will be returned in association with this cdevMonitorNode and, // * therefore, the cdevMessage's operationCode should be set to indicate // * that. // * // * Note that the data parameter should be populated with all of the // * properties that are associated with the particular device / attribute // * pair. // * // * This method will return 0 if any monitors were actually dispatched, // * otherwise it will return -1. // ***************************************************************************** int cdevMonitorNode::fireMonitor( cdevMonitorEntry * entry, int property, cdevMonitorData *data, int endOfTransaction ) { int result = -1; if(entry!=NULL && data!=NULL) { int found = 0; // ************************************************************* // * An operationCode value with bit one set indicates that this // * is NOT the end of the transaction, an operationCode value // * with bit one unset indicates that this IS the end of the // * transaction. // ************************************************************* entry->message->setOperationCode(endOfTransaction?0:1); for(int i=0; !found && itrigCnt; i++) { if(property<0 || entry->triggers[i]==property) { if(property>0) found = 1; // ********************************************* // * Trigger type 3 means that the callback // * wants the changed value and all other // * values that were specified in the // * context. // ********************************************* if(entry->trigType[i]==3) data->setCriticalTags(entry->properties, entry->propCnt); // ********************************************* // * Trigger type 2 means that the callback // * wants only the changed value. // ********************************************* if(entry->trigType[i]==2) data->setCriticalTags(&entry->triggers[i], 1); // ********************************************* // * Determine if the changed data item exists // * in the user provided data. If it does, // * then execute the fireCallback method on // * the cdevMonitorTable to dispatch the // * monitor. // ********************************************* if(data->getType(entry->triggers[i])!=CDEV_INVALID) { // ************************************* // * Added to support multi-device // ************************************* if(entry->message->getDeviceCount()>1) data->insert(cdevMonitorEntry::DEVICE_TAG, entry->message->getDeviceList() [entry->deviceIdx]); entry->message->setData(data, 1); parent->fireCallback(entry->message); // ************************************* // * Added to support multi-device // ************************************* if(entry->message->getDeviceCount()>0) data->remove(cdevMonitorEntry::DEVICE_TAG); result = 0; } } } } return result; } // ***************************************************************************** // * cdevMonitorTable::cdevMonitorTable : // * This is the constructor for the cdevMonitortable class. This class // * contains a hash table that maintains a list of all of the monitored // * device / attribute pairs on the system. // ***************************************************************************** cdevMonitorTable::cdevMonitorTable ( void ) : monitors(0) { } // ***************************************************************************** // * cdevMonitorTable::~cdevMonitorTable : // * This method walks through the monitors hash table and deletes all // * cdevMonitorNodes that have been allocated. // ***************************************************************************** cdevMonitorTable::~cdevMonitorTable ( void ) { char * ptr; StringHashIterator iter(&monitors); iter.first(); while((ptr= iter.key())!=NULL) { cdevMonitorNode * node = (cdevMonitorNode *)iter.data(); monitors.remove(ptr); delete node; iter.first(); } } // ***************************************************************************** // * cdevMonitorTable::insertMonitor: // * This method allows the caller to add a new monitored device / attribute // * pair to the cdevMonitorTable. // * // * The cdevData object that is provided in the cdevData object is the // * collection of all current property values for the device / attribute // * pair. This data will be used to automatically dispatch the first // * callback when the monitor is initially installed. // ***************************************************************************** int cdevMonitorTable::insertMonitor ( cdevMessage * request, cdevData * data ) { return insertMonitor(request, &data, 1); } // ***************************************************************************** // * cdevMonitorTable::insertMonitor: // * This method allows the caller to add a new monitored device / attribute // * pair to the cdevMonitorTable. // * // * The cdevData objects that are provided in the data parameter are the // * initial values for each item in the deviceList in sequence. This data // * will be used to automatically dispatch the first callback when the // * monitor is initially installed. // ***************************************************************************** int cdevMonitorTable::insertMonitor ( cdevMessage * request, cdevData ** data, size_t dataCnt ) { if(request!=NULL && request->getDeviceList()!=NULL && request->getMessage()!=NULL) { char * attrib = strchr(request->getMessage(), ' '); if(attrib) { attrib++; cdevMonitorNode * node; cdevMessage ** msgList; // ***************************************************** // * Allocate additional cdevMessage objects if a // * deviceList greater than 1 is specified. // ***************************************************** if(request->getDeviceCount()>1) { msgList = new cdevMessage *[request->getDeviceCount()]; msgList[0] = request; } else msgList = &request; // ***************************************************** // * Walk through each device in the list. // ***************************************************** for(int i=0; igetDeviceCount(); i++) { if(i>0) msgList[i] = new cdevMessage(*request); if((node=findMonitor(request->getDeviceList()[i], attrib))==NULL) { node = new cdevMonitorNode(this, request->getDeviceList()[i], attrib); monitors.insert(node->getHashString(), node); } if(dataCnt>0 && data!=NULL) { node->insertMonitor(msgList[i], ((iinsertMonitor(msgList[i], NULL, i); } // ***************************************************** // * Delete the containing array of cdevMessage pointers // ***************************************************** if(request->getDeviceCount()>1) delete msgList; } } return 0; } // ***************************************************************************** // * cdevMonitorTable::removeMonitor : // * This method allows the caller to remove a specific monitor using the // * cancelTransIndex component of the cdevMessage object. // ***************************************************************************** int cdevMonitorTable::removeMonitor ( cdevMessage * request ) { int cancelTransIndex = request->getCancelTransIndex(); if(cancelTransIndex > 0) { StringHashIterator iter(&monitors); iter.first(); while(iter.key()!=NULL) { cdevMonitorNode * node = (cdevMonitorNode *)iter.data(); node->removeMonitor(cancelTransIndex); ++iter; } } return 0; } // ***************************************************************************** // * cdevMonitorTable::removeClientMonitors : // * This method will walk through the hash table and will remove all // * monitors that are associated with a specific clientID. // ***************************************************************************** int cdevMonitorTable::removeClientMonitors ( short clientID, int fire ) { char * ptr; StringHashIterator iter(&monitors); iter.first(); while((ptr= iter.key())!=NULL) { cdevMonitorNode * node = (cdevMonitorNode *)iter.data(); node->removeClientMonitors(clientID, fire); iter++; } return 0; } // ***************************************************************************** // * cdevMonitorTable::findMonitor : // * This method locates a cdevMonitorNode associated with the specified // * device / attribute pair and returns it to the caller. // ***************************************************************************** cdevMonitorNode * cdevMonitorTable::findMonitor ( char * device, char * attrib ) { char hashString [512]; sprintf(hashString, "%s %s", device, attrib); return (cdevMonitorNode *)monitors.find(hashString); } // ***************************************************************************** // * cdevMonitorTable:fireMonitor : // * This method is used to deploy all monitors associated with the // * device / attribute / property set. // * // * If the property parameter is NULL, then all properties will be fired // * for all monitor associated with the device / attribute pair. // ***************************************************************************** int cdevMonitorTable::fireMonitor ( char * device, char * attrib, char * property, cdevData * data ) { cdevMonitorNode * node = findMonitor(device, attrib); return node==NULL?-1:node->fireMonitor(property, data); } // ***************************************************************************** // * cdevMonitorTable:fireMonitor : // * This method is used to deploy all monitors associated with the // * device / attribute / property set. // * // * If the property parameter is -1, then all properties will be fired // * for all monitors associated with the device / attribute pair. // ***************************************************************************** int cdevMonitorTable::fireMonitor ( char * device, char * attrib, int property, cdevData * data ) { cdevMonitorNode * node = findMonitor(device, attrib); return node==NULL?-1:node->fireMonitor(property, data); } // ***************************************************************************** // * cdevMonitorTable::fireCallback : // * This is a stub for the fireCallback method that must b e provided by // * the developer. This method is provided here - because this method may // * potentially be called during program termination - resulting in the // * attempted execution of a pure virtual function. // ***************************************************************************** int cdevMonitorTable::fireCallback ( cdevMessage * /* message */ ) { return CDEV_SUCCESS; }