void releaseDispatch(DISPATCH_PTR dispatch) { if (dispatch) { if (dispatch->refCount == 0) { LOG2("\nWARNING: Releasing an unreserved dispatch %s (%d)\n", dispatch->msg->msgData->name, dispatch->locId); } else { dispatch->refCount--; } if (dispatch->refCount <= 0) { #ifndef NMP_IPC HandleKillAfterAttendingNodes(dispatch); if ((dispatch->status == HandledDispatch) && !dispatch->treeNode) { dispatchFree(dispatch); #else if (dispatch->status == HandledDispatch) { dispatchFree(dispatch); #endif } } } } /****************************************************************************** * * FUNCTION: void dispatchStats * * DESCRIPTION: Print stats about the utilization of dispatches in central * * INPUTS: * * OUTPUTS: * *****************************************************************************/ #if 0 /* No longer used */ void dispatchStats () { int32 i, num=0; DISPATCH_PTR dispatch; for (i=0; i<GET_S_GLOBAL(dispatchTable)->currentSize; i++) { dispatch = (DISPATCH_PTR)idTableItem(i, GET_S_GLOBAL(dispatchTable)); if (dispatch->status != UnallocatedDispatch) { printf("%d. %s\n", ++num, dispatch->msg->msgData->name); } } }
void recvMessageBuild(MODULE_PTR module, DATA_MSG_PTR dataMsg) { char *classData; MSG_PTR msg = NULL; DISPATCH_PTR dispatch; X_IPC_MSG_CLASS_TYPE msg_class; CLASS_FORM_PTR classForm; CONST_FORMAT_PTR classFormat = NULL; if (dataMsg->intent != NO_REF) msg = (MSG_PTR)idTableItem(ABS(dataMsg->intent), GET_C_GLOBAL(msgIdTable)); msg_class = (X_IPC_MSG_CLASS_TYPE)dataMsg->classId; classForm = GET_CLASS_FORMAT(&msg_class); if (classForm) classFormat = classForm->format; classData = (char *)x_ipc_dataMsgDecodeClass(classFormat, dataMsg); if (dataMsg->dispatchRef != NO_REF) { dispatch = DISPATCH_FROM_ID(dataMsg->dispatchRef); } else { dispatch = dispatchAllocate(); dispatch->msg = msg; dispatch->org = module; dispatch->orgId = module->readSd; dispatch->refId = dataMsg->msgRef; dispatch->pRef = dataMsg->parentRef; } if (dispatch == NULL) /* Probably a reply that was not needed */ return; if (dataMsg->msgRef == NO_REF) dispatchSetResData(dataMsg, dispatch); else dispatchSetMsgData(dataMsg, dispatch); /* 22-May-91: fedor: NOTE: class and classData will change if this is a previously created dispatch. This may be undesired for behavior for a x_ipc_sendResponse call that refers to a previously created dispatch. */ /* 3-Jul-91: reid: Clean up previous class data, except for command class data, which is stored in blockCom */ if (dispatch->classData && dispatch->msg_class != CommandClass) x_ipc_classDataFree(dispatch->msg_class, dispatch->classData); /* RGS 1/11/01: This prevents a reply from being sent when it shouldn't be. The problem is that with IPC, one can have a message sent to a query handler without expecting a reply (e.g, using a broadcast rather than a QueryClass). */ if (msg_class == ReplyClass && (dispatch->msg_class != QueryClass && dispatch->msg_class != MultiQueryClass)) { msg_class = SuccessClass; } dispatch->msg_class = msg_class; dispatch->classData = classData; recvMessage(dispatch, msg_class, classData); }