/****************************************************************************** * * FUNCTION: void x_ipcReferenceRelease(ref) * * DESCRIPTION: * Frees the reference and * * INPUTS: X_IPC_REF_PTR ref; * * OUTPUTS: none * *****************************************************************************/ void x_ipcReferenceRelease(X_IPC_REF_PTR ref) { if (ref) { (void)x_ipcInform(X_IPC_REF_RELEASE_INFORM, (void *)&(ref->refId)); x_ipcRefFree(ref); } }
void *x_ipcReferenceData(X_IPC_REF_PTR ref) { int32 refId, sd; MSG_PTR msg; char *msgData; X_IPC_REF_PTR waitRef; X_IPC_RETURN_VALUE_TYPE returnValue; msg = x_ipc_msgFind(X_IPC_REF_DATA_QUERY); if (msg == NULL) return NULL; if (!ref->msg) { if (!ref->name) { /* 17-Jun-91: fedor: start enforcing correct refs */ X_IPC_MOD_ERROR1("ERROR: x_ipcReferenceData: Badly Formed Reference: %d\n", ref->refId); return NULL; } ref->msg = x_ipc_msgFind(ref->name); if (ref->msg == NULL) return NULL; } /* 17-Jun-91: fedor: check if any message form */ if (!ref->msg->msgData->msgFormat) return NULL; refId = x_ipc_nextSendMessageRef(); returnValue = x_ipc_sendMessage((X_IPC_REF_PTR)NULL, msg, (char *)&ref->refId, (char *)NULL, refId); if (returnValue != Success) { X_IPC_MOD_ERROR("ERROR: x_ipcReferenceData: x_ipc_sendMessage Failed.\n"); return NULL; } waitRef = x_ipcRefCreate(ref->msg, ref->name, refId); msgData = (char *)x_ipcMalloc((unsigned)x_ipc_dataStructureSize(ref->msg->msgData->msgFormat)); LOCK_CM_MUTEX; sd = GET_C_GLOBAL(serverRead); UNLOCK_CM_MUTEX; returnValue = x_ipc_waitForReplyFrom(waitRef, msgData, TRUE, WAITFOREVER, sd); x_ipcRefFree(waitRef); if (returnValue == NullReply) { /* 17-Jun-91: fedor: if NullReply then nothing else was malloced. */ x_ipcFree(msgData); return NULL; } else return msgData; }
void x_ipcUnlockResource(X_IPC_REF_PTR ref) { if (STREQ(ref->name, X_IPC_LOCK_RESOURCE_QUERY) || STREQ(ref->name, X_IPC_LOCK_MOD_RESOURCE_QUERY)) { (void)x_ipcInform(X_IPC_UNLOCK_RESOURCE_INFORM, (void *)&(ref->refId)); x_ipcRefFree(ref); } else { X_IPC_MOD_ERROR("ERROR: x_ipcUnlockResource: X_IPC_REF_PTR not a lock.\n"); } }
void x_ipcCancelReservation(X_IPC_REF_PTR ref) { if (STREQ(ref->name, X_IPC_RESERVE_RESOURCE_QUERY) || STREQ(ref->name, X_IPC_RESERVE_MOD_RESOURCE_QUERY)) { (void)x_ipcInform(X_IPC_CANCEL_RESOURCE_INFORM, (void *)&(ref->refId)); x_ipcRefFree(ref); } else { X_IPC_MOD_ERROR("ERROR: x_ipcCancelReservation: X_IPC_REF_PTR not a reservation.\n"); } }
static void x_ipc_freeContext(X_IPC_CONTEXT_PTR *context) { if (!*context) return; x_ipcFree((char *)(*context)->servHostGlobal); x_ipc_freeContextList(&((*context)->queryNotificationList)); x_ipc_freeContextList(&((*context)->connectNotifyList)); x_ipc_freeContextList(&((*context)->disconnectNotifyList)); x_ipc_freeContextList(&((*context)->changeNotifyList)); LOCK_M_MUTEX; x_ipcRefFree(GET_M_GLOBAL(x_ipcRootNodeGlobal)); GET_M_GLOBAL(x_ipcRootNodeGlobal) = NULL; UNLOCK_M_MUTEX; x_ipc_freeContextList(&((*context)->x_ipcRefFreeList)); x_ipc_hashTableFree(&((*context)->moduleConnectionTable), x_ipc_hashItemsFree, NULL); x_ipc_hashTableFree(&((*context)->handlerTable), (HASH_ITER_FN) x_ipc_hndFree, NULL); x_ipc_hashTableFree(&((*context)->messageTable), (HASH_ITER_FN) x_ipc_msgFree, NULL); x_ipc_hashTableFree(&((*context)->resourceTable),x_ipc_hashItemsFree, NULL); x_ipc_idTableFree(&(*context)->hndIdTable); x_ipc_idTableFree(&(*context)->msgIdTable); x_ipc_listFreeAllItems((LIST_FREE_FN)x_ipc_dataMsgFree, (*context)->pendingReplies); x_ipc_listFree(&((*context)->pendingReplies)); (*context)->pendingReplies = NULL; x_ipcFree((char *)(*context)->msgQueue.messages); initMsgQueue(&(*context)->msgQueue); x_ipc_strListFree(&((*context)->tappedMsgs),TRUE); x_ipc_strListFree(&((*context)->broadcastMsgs),TRUE); x_ipc_listFree(&((*context)->queryNotificationList)); x_ipcFree((char *)*context); *context = NULL; }
X_IPC_RETURN_VALUE_TYPE x_ipc_sendResponse(X_IPC_REF_PTR ref, MSG_PTR msg, void *resData, X_IPC_MSG_CLASS_TYPE resClass, void *resClassData, int sd) { int32 intent=-1, refId,msgId=-1; CONST_FORMAT_PTR format; DATA_MSG_PTR dataMsg; CLASS_FORM_PTR classForm; CONST_FORMAT_PTR classFormat; X_IPC_RETURN_STATUS_TYPE result; #ifdef NMP_IPC if (ref->responded == TRUE) { /* Already responded -- something is wrong! */ X_IPC_MOD_ERROR2("x_ipc_sendResponse: Already responed to instance %d (%s)\n", ref->refId, ref->msg->msgData->name); } #endif classFormat = NULL; format = NULL; if (msg) { #ifndef NMP_IPC intent = msg->msgData->refId; format = msg->msgData->resFormat; #else /* The only place X_IPC calls this function with "msg" set is in fireDemon. Since IPC doesn't use that, we should be safe using "msg" for another reason */ format = msg->msgData->msgFormat; if (!ref->msg) { ref->msg = x_ipc_msgFind(ref->name); if (ref->msg == NULL) return MsgUndefined; } if (ref->msg->direct) { intent = QUERY_REPLY_INTENT; msgId = ref->refId; } else { intent = -1; } /* We have to "fool" the receiver of the response into using this message for encoding/decoding, rather than the query message. Not pretty, but it works. Depends on the fact that ReplyClass has no class data. Later, rework central so that it knows how to handle this case explicitly. */ { int resClass1 = ExecHndClass; /* Format for ExecHndClass is "string" -- used to send the message name */ LOCK_M_MUTEX; classForm = GET_CLASS_FORMAT(&resClass1); UNLOCK_M_MUTEX; classFormat = classForm->format; resClassData = (void *)&(msg->msgData->name); } #endif } else { if (ref) { if (!ref->msg) { ref->msg = x_ipc_msgFind(ref->name); if (ref->msg == NULL) return MsgUndefined; } if (resData != NULL) format = ref->msg->msgData->resFormat; msg = ref->msg; if (msg->direct){ intent = QUERY_REPLY_INTENT; msgId = ref->refId; } else { intent = -1; } } } LOCK_M_MUTEX; classForm = GET_CLASS_FORMAT(&resClass); UNLOCK_M_MUTEX; if (classForm) classFormat = classForm->format; refId = (ref ? ref->refId : NO_REF); LOCK_CM_MUTEX; dataMsg = x_ipc_dataMsgCreate(GET_C_GLOBAL(parentRefGlobal), intent, (int32)resClass, refId, msgId, (FORMAT_PTR)format, resData, (FORMAT_PTR)classFormat, resClassData); UNLOCK_CM_MUTEX; if (dataMsg == NULL) return Failure; result = x_ipc_dataMsgSend(sd, dataMsg); #ifdef NMP_IPC if (result == StatOK) { if (ref->responded == -1) { /* Happening outside of the handler -- nuke the reference */ x_ipcRefFree(ref); } else ref->responded = TRUE; } #endif x_ipc_dataMsgFree(dataMsg); return (result != StatOK ? Failure : Success); }
IPC_RETURN_TYPE _IPC_queryResponse (const char *msgName, unsigned int length, BYTE_ARRAY content, BYTE_ARRAY *replyHandle, FORMATTER_PTR *replyFormatterPtr, const char **responseMsgNamePtr, unsigned int timeoutMsecs) { unsigned long quitTime = WAITFOREVER, now; QUERY_REPLY_TYPE queryReplyData; QUERY_NOTIFICATION_PTR queryNotif; IPC_RETURN_TYPE retVal = IPC_OK; queryReplyData.handled = FALSE; queryReplyData.data = NULL; queryReplyData.formatter = (FORMATTER_PTR)NULL; queryReplyData.msgName = NULL; if (timeoutMsecs != IPC_WAIT_FOREVER) { /* When to timeout */ now = x_ipc_timeInMsecs(); quitTime = timeoutMsecs + now; } /* Send the query, and set up a handler to catch the result and squirrel away the response data in "queryReplyData" */ if (IPC_queryNotify(msgName, length, content, queryReplyHandler, &queryReplyData) == IPC_Error) { PASS_ON_ERROR(); } else { /* Check if completed, because in threaded IPC, another thread could have handled the notification already */ if (!queryReplyData.handled) { while ((retVal = IPC_listen(timeoutMsecs)) == IPC_OK && !queryReplyData.handled) { /* Handled a message, but not the one we are waiting for. If still have time, reset the timeout and try again */ if (timeoutMsecs != IPC_WAIT_FOREVER) { now = x_ipc_timeInMsecs(); if (quitTime < now) { retVal = IPC_Timeout; break; } else { timeoutMsecs = quitTime - now; } } } } if (retVal != IPC_OK) { /* Clean up */ LOCK_CM_MUTEX; queryNotif = ((QUERY_NOTIFICATION_PTR) x_ipc_listMemReturnItem((LIST_ITER_FN)testQueryReplyData, (char *)&queryReplyData, GET_C_GLOBAL(queryNotificationList))); x_ipc_listDeleteItem((void *)queryNotif, GET_C_GLOBAL(queryNotificationList)); UNLOCK_CM_MUTEX; x_ipcRefFree(queryNotif->ref); x_ipcFree((void *)queryNotif); } *replyHandle = queryReplyData.data; if (replyFormatterPtr) *replyFormatterPtr = queryReplyData.formatter; if (responseMsgNamePtr) *responseMsgNamePtr = queryReplyData.msgName; return retVal; } }