示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
  }
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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");
  }
}
示例#8
0
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");
  }
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}