void x_ipc_msgInfoMsgInitialize(void) { int32 refId; MSG_DATA_PTR msgData; LOCK_CM_MUTEX; LOCK_IO_MUTEX; if (x_ipc_readNBytes(GET_C_GLOBAL(serverRead), (char *)&refId, sizeof(int32)) != StatOK) { GET_C_GLOBAL(serverRead) = NO_SERVER_GLOBAL; GET_C_GLOBAL(serverWrite) = NO_SERVER_GLOBAL; X_IPC_MOD_ERROR("ERROR: Socket connection broken or access denied to central server\n"); UNLOCK_IO_MUTEX; UNLOCK_CM_MUTEX; return; } NET_INT_TO_INT(refId); msgData = NEW(MSG_DATA_TYPE); msgData->refId = refId; msgData->name = strdup(X_IPC_MSG_INFO_QUERY); msgData->msg_class = QueryClass; msgData->msgFormat = (FORMAT_PTR)x_ipc_formatterRecv(GET_C_GLOBAL(serverRead)); msgData->resFormat = (FORMAT_PTR)x_ipc_formatterRecv(GET_C_GLOBAL(serverRead)); UNLOCK_IO_MUTEX; UNLOCK_CM_MUTEX; (void)x_ipc_msgCreate(msgData); }
static void x_ipc_listIncFreeList(void) #endif { int32 i; LIST_PTR newList; LOCK_LIST_MUTEX; for(i=1;i < LIST_INC_AMOUNT;i++) { #if defined(DBMALLOC) newList = NEW_DB(file,line,LIST_TYPE); #else newList = NEW(LIST_TYPE); #endif if (!newList) { X_IPC_MOD_ERROR("Error: Can not increment list top level free list."); UNLOCK_LIST_MUTEX; return; } newList->length = 0; newList->first = NULL; newList->last = NULL; newList->next = NULL; /* No need to lock M_MUTEX, since list.c is only place this is accessed */ newList->freeList = GET_M_GLOBAL(listFreeListGlobal); GET_M_GLOBAL(listFreeListGlobal) = newList; } UNLOCK_LIST_MUTEX; }
static CONST_FORMAT_PTR x_ipc_formatterRecv(int sd) { DATA_MSG_PTR dataMsg = NULL; CONST_FORMAT_PTR *pointerToFormat; CONST_FORMAT_PTR format; NAMED_FORMAT_PTR formatFormat; LOCK_M_MUTEX; formatFormat = (NAMED_FORMAT_PTR) x_ipc_hashTableFind("format", GET_M_GLOBAL(formatNamesTable)); UNLOCK_M_MUTEX; if (!formatFormat) { X_IPC_MOD_ERROR("ERROR: x_ipc_formatterRecv: no formatFormat"); } switch(x_ipc_dataMsgRecv(sd, &dataMsg, 0, NULL, 0)){ case StatOK: pointerToFormat = (CONST_FORMAT_PTR *) x_ipc_dataMsgDecodeMsg(formatFormat->format, dataMsg, FALSE); x_ipc_dataMsgFree(dataMsg); format = *pointerToFormat; x_ipcFree((void *)pointerToFormat); return(format); case StatError: X_IPC_MOD_ERROR("ERROR: foramatterRecv: x_ipc_dataMsgRecv: StatError:"); /*NOTREACHED*/ break; case StatEOF: X_IPC_MOD_ERROR("ERROR: foramatterRecv: x_ipc_dataMsgRecv: StatEOF:"); /*NOTREACHED*/ break; case StatSendEOF: case StatSendError: case StatRecvEOF: case StatRecvError: X_IPC_MOD_ERROR("ERROR: foramatterRecv: x_ipc_dataMsgRecv: Unexpected error \n"); break; #ifndef TEST_CASE_COVERAGE default: X_IPC_MOD_ERROR("ERROR: foramatterRecv: x_ipc_dataMsgRecv: UNKNOWN:"); /*NOTREACHED*/ #endif } return ( CONST_FORMAT_PTR) NULL; }
const char *x_ipcReferenceName(X_IPC_REF_PTR ref) { if (ref->name == NULL) { X_IPC_MOD_ERROR("ERROR: x_ipcReferenceName: invalid x_ipc reference pointer.\n"); return NULL; } else { return ref->name; } }
DATA_MSG_PTR x_ipc_dataMsgReplaceClassData(CONST_FORMAT_PTR classFormat, void *data, DATA_MSG_PTR dataMsg, CONST_FORMAT_PTR msgFormat) { #ifdef UNUSED_PRAGMA #pragma unused(msgFormat) #endif DATA_MSG_PTR newDataMsg; int32 classTotal=0; if (data && classFormat) classTotal = x_ipc_bufferSize(classFormat, data); newDataMsg = x_ipc_dataMsgAlloc(sizeof(DATA_MSG_TYPE)+classTotal); /* 3-Sep-90: fedor: this should work because class info is in the dataMsg struture as the last item. */ BCOPY((char *)dataMsg, (char *)newDataMsg, sizeof(DATA_MSG_TYPE)); if (classTotal) { newDataMsg->classData = ((char *)newDataMsg + sizeof(DATA_MSG_TYPE)); x_ipc_encodeData(classFormat, data, newDataMsg->classData, 0, classTotal); newDataMsg->classByteOrder = BYTE_ORDER; } else newDataMsg->classData = NULL; /* reset msgData pointer */ newDataMsg->msgData = dataMsg->msgData; newDataMsg->dataStruct = dataMsg->dataStruct; dataMsg->msgData = NULL; /* Need to copy the vector data. */ if (dataMsg->vec != NULL) newDataMsg->vec = x_ipc_copyVectorization(dataMsg->vec,0); else { X_IPC_MOD_ERROR("Internal Error: Missing data Vector\n"); return NULL; } /* set refCount */ newDataMsg->dataRefCountPtr = dataMsg->dataRefCountPtr; if ( newDataMsg->dataRefCountPtr != NULL) (*(newDataMsg->dataRefCountPtr))++; newDataMsg->refCount = 0; newDataMsg->classTotal = classTotal; if (x_ipc_dataMsgFree(dataMsg) != NULL) dataMsg->msgData = newDataMsg->msgData; return newDataMsg; }
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_listIncCellFreeList(void) { int32 i; LIST_ELEM_PTR newCell; LOCK_LIST_MUTEX; for(i=1;i<LIST_CELL_INC_AMOUNT;i++) { newCell = NEW(LIST_ELEM_TYPE); if (!newCell) { X_IPC_MOD_ERROR("Error: Can not increment list element free list."); UNLOCK_LIST_MUTEX; return; } newCell->item = NULL; newCell->previous = NULL; /* No need to lock M_MUTEX, since list.c is only place this is accessed */ newCell->next = GET_M_GLOBAL(listCellFreeListGlobal); GET_M_GLOBAL(listCellFreeListGlobal) = newCell; } UNLOCK_LIST_MUTEX; }
X_IPC_RETURN_STATUS_TYPE x_ipc_dataMsgRecv(int sd, DATA_MSG_PTR *dataMsg, int32 replyRef, void *replyBuf, int32 replyLen) { X_IPC_RETURN_STATUS_TYPE status; DATA_MSG_TYPE header; *dataMsg = NULL; LOCK_IO_MUTEX; status = x_ipc_readNBytes(sd, (char *)&(header.classTotal), HEADER_SIZE()); if (status != StatOK) { *dataMsg = NULL; UNLOCK_IO_MUTEX; return status; } NET_INT_TO_INT(header.classTotal); NET_INT_TO_INT(header.msgTotal); *dataMsg = x_ipc_dataMsgAlloc(header.classTotal + sizeof(DATA_MSG_TYPE)); **dataMsg = header; NET_INT_TO_INT((*dataMsg)->parentRef); NET_INT_TO_INT((*dataMsg)->intent); NET_INT_TO_INT((*dataMsg)->classId); NET_INT_TO_INT((*dataMsg)->dispatchRef); NET_INT_TO_INT((*dataMsg)->msgRef); if( header.msgTotal > 0) { (*dataMsg)->dataRefCountPtr = (int32 *)x_ipcMalloc(sizeof(int32)); *((*dataMsg)->dataRefCountPtr) = 1; } else { (*dataMsg)->dataRefCountPtr = NULL; } (*dataMsg)->refCount = 0; (*dataMsg)->dataStruct = NULL; (*dataMsg)->dataByteOrder = GET_DATA_ENDIAN((*dataMsg)->classId); (*dataMsg)->classByteOrder = GET_CLASS_ENDIAN((*dataMsg)->classId); (*dataMsg)->alignment = (ALIGNMENT_TYPE)GET_ALIGNMENT((*dataMsg)->classId); (*dataMsg)->classId = GET_CLASSID((*dataMsg)->classId); LOCK_M_MUTEX; GET_M_GLOBAL(byteOrder) = (*dataMsg)->dataByteOrder; GET_M_GLOBAL(alignment) = (*dataMsg)->alignment; UNLOCK_M_MUTEX; if (header.classTotal > 0) (*dataMsg)->classData = ((char *)*dataMsg + sizeof(DATA_MSG_TYPE)); else (*dataMsg)->classData = NULL; /* For now, we only handle packed data. */ if ((*dataMsg)->alignment != ALIGN_PACKED) { X_IPC_MOD_ERROR("ERROR: received message with data that is not packed."); UNLOCK_IO_MUTEX; return StatError; } /* Want to be able to use the already allocated buffer, if possible. */ if (((*dataMsg)->msgRef == replyRef) && (replyBuf != NULL) && (replyLen == header.msgTotal)) { (*dataMsg)->msgData = (char *)replyBuf; (*dataMsg)->dataStruct = (char *)replyBuf; } else if (header.msgTotal > 0) (*dataMsg)->msgData = (char *)x_ipcMalloc((unsigned) header.msgTotal); else (*dataMsg)->msgData = NULL; if ((header.msgTotal > 0) && (header.classTotal >0)) { status = x_ipc_read2Buffers(sd, (*dataMsg)->classData, header.classTotal, (*dataMsg)->msgData, header.msgTotal); } else if (header.classTotal > 0) { status = x_ipc_readNBytes(sd, (*dataMsg)->classData, header.classTotal); } else if (header.msgTotal > 0) { status = x_ipc_readNBytes(sd, (*dataMsg)->msgData, header.msgTotal); } /* Need to create the vector here. */ (*dataMsg)->vec = (struct iovec *)x_ipcMalloc(2 * sizeof(struct iovec)); (*dataMsg)->vec[0].iov_base = (*dataMsg)->msgData; (*dataMsg)->vec[0].iov_len = (*dataMsg)->msgTotal; (*dataMsg)->vec[1].iov_base = NULL; (*dataMsg)->vec[1].iov_len = 0; UNLOCK_IO_MUTEX; return status; }
static X_IPC_RETURN_STATUS_TYPE x_ipc_writeNBuffers(int sd, struct iovec *vec, int32 amount) { int32 amountWritten = 0; int32 numBuffers=0; int32 amountToWrite=0; int32 i, start=0; BOOLEAN *pipeBrokenPtr; for (i=0; (vec[i].iov_base != NULL); i++) { numBuffers++; amountToWrite += vec[i].iov_len; } if (amountToWrite != amount) { X_IPC_MOD_ERROR("Internal Error: Amounts incorrect in msg send.\n"); return StatError; } LOCK_IO_MUTEX; LOCK_M_MUTEX; pipeBrokenPtr = &GET_M_GLOBAL(pipeBroken); UNLOCK_M_MUTEX; while (amountToWrite > 0) { *pipeBrokenPtr = FALSE; #ifndef OS2 errno = 0; #endif SAFE_IO(amountWritten, writev(sd, &vec[start], numBuffers)); if (*pipeBrokenPtr || (errno == EPIPE)) { X_IPC_MOD_WARNING( "\nWARNING: pipe broken!\n"); x_ipcFree((char *)vec); UNLOCK_IO_MUTEX; return StatError; } else if (amountWritten < 0) { #if defined(VXWORKS) || defined(THINK_C) || defined(macintosh) x_ipcFree((char *)vec); UNLOCK_IO_MUTEX; return StatError; #else #ifdef _WINSOCK_ if (WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EWOULDBLOCK) #endif { X_IPC_MOD_WARNING( "\nWARNING: x_ipc_writeNBytes: EWOULDBLOCK: trying again!\n"); PAUSE_MIN_DELAY(); } else { x_ipcFree((char *)vec); UNLOCK_IO_MUTEX; return StatError; } #endif } else { amountToWrite -= amountWritten; if (amountToWrite > 0) { while (amountWritten > 0) { if (vec[start].iov_len <= amountWritten) { amountWritten -= vec[start].iov_len; start++; numBuffers--; } else if (vec[start].iov_len > amountWritten) { vec[start].iov_len -= amountWritten; #ifndef _SGI_SOURCE vec[start].iov_base += amountWritten; #else vec[start].iov_base = (caddr_t)((int32)vec[start].iov_base + amountWritten); #endif amountWritten = 0; } } } } } UNLOCK_IO_MUTEX; x_ipcFree((char *)vec); return StatOK; }
X_IPC_RETURN_VALUE_TYPE x_ipc_sendMessage(X_IPC_REF_PTR ref, MSG_PTR msg, void *msgData, void *classData, int32 preallocatedRefId) { int32 refId, savedRef, i, sd; DATA_MSG_PTR msgDataMsg; X_IPC_MSG_CLASS_TYPE msg_class; CLASS_FORM_PTR classForm; CONST_FORMAT_PTR classFormat; X_IPC_RETURN_STATUS_TYPE result; DIRECT_MSG_HANDLER_PTR direct; CONNECTION_PTR connection; classFormat = NULL; if (!msg) { X_IPC_MOD_ERROR("ERROR: x_ipc_sendMessage: NULL msg.\n"); } if (!x_ipc_isValidServerConnection()) { X_IPC_MOD_ERROR("ERROR: Must be connected to the server to send a message"); return Failure; } /* save the message ref to use in case x_ipc_msgFind triggers a recursive call to x_ipc_sendMessage */ LOCK_CM_MUTEX; savedRef = (preallocatedRefId != NO_REF ? preallocatedRefId : x_ipc_nextSendMessageRef()); msg_class = msg->msgData->msg_class; classForm = GET_CLASS_FORMAT(&msg_class); if (classForm) classFormat = classForm->format; refId = (ref ? ref->refId : NO_REF); /* RTG For now, only do direct if no logging. */ msgDataMsg = x_ipc_dataMsgCreate(GET_C_GLOBAL(parentRefGlobal), -1, (int32)msg_class, refId, savedRef, msg->msgData->msgFormat, msgData, (FORMAT_PTR)classFormat, classData); UNLOCK_CM_MUTEX; if (msgDataMsg == NULL) { X_IPC_MOD_ERROR1("Unable to send message %s, probably a bad format\n", msg->msgData->name); return Failure; } if (!msg->direct || !msg->directList || msg->directList->numHandlers == 0) { msgDataMsg->intent = msg->msgData->refId; LOCK_CM_MUTEX; sd = GET_C_GLOBAL(serverWrite); UNLOCK_CM_MUTEX; result = x_ipc_dataMsgSend(sd, msgDataMsg); } else { /* Send in reverse order (to match what happens within central) */ for (i=msg->directList->numHandlers-1, result=StatOK; i>=0 && result == StatOK; i--) { direct = &(msg->directList->handlers[i]); if (direct->readSd >= 0) { msgDataMsg->intent = direct->intent; result = x_ipc_dataMsgSend(direct->writeSd, msgDataMsg); if (result == StatError && errno == EPIPE) { fprintf(stderr, "Need to close %d\n", direct->writeSd); LOCK_CM_MUTEX; connection = (CONNECTION_PTR)x_ipc_hashTableFind((void *)&direct->writeSd, GET_C_GLOBAL(moduleConnectionTable)); UNLOCK_CM_MUTEX; if (connection) { x_ipcHandleClosedConnection(direct->writeSd, connection); result = StatOK; } } } } } x_ipc_dataMsgFree(msgDataMsg); if (result != StatOK) return Failure; return Success; }