IPC_RETURN_TYPE _IPC_subscribe (const char *msgName, const char *hndName, HANDLER_TYPE handler, void *clientData, int autoUnmarshall) { HND_KEY_TYPE hndKey; HND_PTR hnd; if (!msgName || strlen(msgName) == 0) { RETURN_ERROR(IPC_Null_Argument); } else if (!X_IPC_CONNECTED()) { RETURN_ERROR(IPC_Not_Connected); } else { if (!GET_C_GLOBAL(willListen)) X_IPC_MOD_WARNING1("WARNING: Subscribing to %s, " "but have connected no-listen\n", msgName); x_ipcRegisterHandler(msgName, hndName, (X_IPC_HND_FN)handler); /* Set the client data */ hndKey.num = 0; hndKey.str = hndName; LOCK_CM_MUTEX; hnd = GET_HANDLER(&hndKey); UNLOCK_CM_MUTEX; hnd->autoUnmarshall = autoUnmarshall; if (hnd->isRegistered && hnd->clientData != NO_CLIENT_DATA && hnd->clientData != clientData) { X_IPC_MOD_WARNING1("Resetting client data for handler %s\n", hndName); } hnd->isRegistered = TRUE; hnd->clientData = clientData; return IPC_OK; } }
void x_ipc_idTablePrintInfo(ID_TABLE_PTR table) { if (table) { X_IPC_MOD_WARNING1( "idTable: %s\n", table->name); X_IPC_MOD_WARNING1( "free : %d\n", table->freeTotal); X_IPC_MOD_WARNING1( "size : %d\n", table->currentSize); X_IPC_MOD_WARNING1( "incSize: %d\n", table->incSize); } else X_IPC_MOD_WARNING( "x_ipc_idTablePrintInfo: NULL Table\n"); }
X_IPC_REF_PTR x_ipcReserveResource(const char *resName) { int32 refId; MSG_PTR msg; X_IPC_REF_PTR ref; refId = 0; if (x_ipcQuery(X_IPC_RESERVE_RESOURCE_QUERY, (void *)&resName, (void *)&refId) != Success) return NULL; if (refId < 0) { X_IPC_MOD_WARNING( "\nWARNING: Ignoring reservation request.\n"); X_IPC_MOD_WARNING1( "%s is already reserved by this module.\n", resName); ref = CREATE_NULL_REF(); } else { msg = x_ipc_msgFind(X_IPC_RESERVE_RESOURCE_QUERY); if (msg == NULL) return NULL; ref = x_ipcRefCreate(msg, X_IPC_RESERVE_RESOURCE_QUERY, refId); } return ref; }
IPC_RETURN_TYPE IPC_subscribeFD (int fd, FD_HANDLER_TYPE handler, void *clientData) { if (!GET_C_GLOBAL(willListen)) X_IPC_MOD_WARNING1("WARNING: Subscribing to port %d, " "but have connected no-listen\n", fd); x_ipcAddEventHandler(fd, (X_IPC_FD_HND_FN)handler, clientData); return IPC_OK; }
/* TNgo, 5/22/97, added another variable to this function so that it can be called by IPC_connectModule */ IPC_RETURN_TYPE _IPC_connect (const char *taskName, const char *serverName, BOOLEAN willListen) { const char *serverHost; char *colon = NULL; int i, serverPort; struct timeval wait; /* Added by Bob Goode/Tam Ngo, 5/21/97, for WINSOCK option. */ #ifdef OS2 sock_init(); #elif defined(_WINSOCK_) startWinsock(); #endif /* Winsock DLL loading */ if (ipcVerbosity > IPC_Silent) { printf("NMP IPC Version %d.%d.%d (%s)\n", IPC_VERSION_MAJOR, IPC_VERSION_MINOR, IPC_VERSION_MICRO, IPC_VERSION_DATE); } /* Modified by TNgo, 5/22/97 */ serverHost = ((serverName != NULL && strlen(serverName) > 0) ? serverName : x_ipcServerMachine()); for (i=0; i<MAX_RECONNECT_TRIES; i++) { if (i > 0 && ipcVerbosity > IPC_Silent) printf(" Trying again %s to connect with the central server on %s\n", taskName, serverHost); IPC_initialize(); x_ipcWillListen(willListen); x_ipcConnectModule(taskName, serverHost); if (X_IPC_CONNECTED()) { x_ipcWaitUntilReady(); if (ipcVerbosity > IPC_Silent) { colon = (serverHost ? (char *)index((char *)serverHost, ':') : NULL); serverPort = (colon == NULL ? SERVER_PORT : atoi(colon+1)); X_IPC_MOD_WARNING1("... IPC Connected on port %d\n", serverPort); } return IPC_OK; } else { /* Need to do this, rather than sleep, because of SIGALRM's */ wait.tv_sec = RECONNECT_WAIT; wait.tv_usec = 0; select(0, 0, 0, 0, &wait); } } /* At this point, we've been unable to connect */ RETURN_ERROR(IPC_Not_Connected); }
IPC_RETURN_TYPE IPC_addTimerGetRef(unsigned long tdelay, long count, TIMER_HANDLER_TYPE handler, void *clientData, TIMER_REF *timerRef) { TIMER_PTR timer; if (!handler) { RETURN_ERROR(IPC_Null_Argument); } else if (tdelay == 0) { RETURN_ERROR(IPC_Argument_Out_Of_Range); } else if (count <= 0 && count != TRIGGER_FOREVER) { RETURN_ERROR(IPC_Argument_Out_Of_Range); } else { if (0 == timerRef) { /* if IPC_addTimerGetRef() is being called from IPC_addTimer(), we will clobber any old timers with the same handler for backwards compatibility */ timer = ipcGetTimer(handler); if (timer && timer->status != Timer_Deleted) { X_IPC_MOD_WARNING1("Replacing existing timer for handler (%#lx)\n", (long)handler); } else { timer = NEW(TIMER_TYPE); LOCK_M_MUTEX; x_ipc_listInsertItemLast((const void *)timer, GET_M_GLOBAL(timerList)); UNLOCK_M_MUTEX; } } else { /* if IPC_addTimerGetRef() is being called directly with a non-zero timerRef argument, we don't clobber */ timer = NEW(TIMER_TYPE); LOCK_M_MUTEX; x_ipc_listInsertItemLast((const void *)timer, GET_M_GLOBAL(timerList)); UNLOCK_M_MUTEX; } timer->timerFn = handler; timer->period = tdelay; timer->clientData = clientData; timer->maxTrigger = count; timer->triggerTime = x_ipc_timeInMsecs() + tdelay; timer->status = Timer_Waiting; if (0 != timerRef) *timerRef = (TIMER_REF) timer; return IPC_OK; } }
IPC_RETURN_TYPE IPC_removeTimer(TIMER_HANDLER_TYPE handler) { TIMER_PTR timer; if (!handler) { RETURN_ERROR(IPC_Null_Argument); } else { timer = ipcGetTimer(handler); if (!timer) { X_IPC_MOD_WARNING1("Timer for handler (%#x) does not exist\n",handler); } else if (timer->status == Timer_In_Use) { /* Need to delay actually deleting the timer in case this function is called from within "ipcTriggerTimers" */ timer->status = Timer_Deleted; } else { ipcDeleteTimer(timer); } return IPC_OK; } }
void processHandledMessage(DISPATCH_PTR dispatch) { dispatchUpdateAndDisplay(HandledDispatch, dispatch); resourceRemoveAttending(dispatch); tapAfterHandled(dispatch); if (dispatch->msg && !ONE_WAY_MSG(dispatch->msg)) { switch (dispatch->msg_class) { case SuccessClass: #ifndef NMP_IPC tapWhenSuccess(dispatch); tapAfterSuccess(dispatch); #endif break; #ifndef NMP_IPC case FailureClass: tapWhenFailure(dispatch); tapAfterFailure(dispatch); break; #endif default: /* X_IPC_MOD_ERROR("Unhandled default"); */ X_IPC_MOD_WARNING1("unhandled default in processHandledMessage %d\n", dispatch->msg_class); break; } } resourceProcessPending(dispatch); #ifndef NMP_IPC CompletionConstraints(dispatch); HandleKillAfterAttendingNodes(dispatch); #endif if (!dispatch->msg || ONE_WAY_MSG(dispatch->msg)) dispatchFree(dispatch); /* 14-May-91: fedor: exception class messages that are byPassed or retry should not be dispatch freed arbitrarly - may need to declare the first message handled and then resend the same dispatch through recvMessage */ }
IPC_RETURN_TYPE IPC_removeTimerByRef(TIMER_REF timerRef) { TIMER_PTR timer; if (!timerRef) { RETURN_ERROR(IPC_Null_Argument); } else { timer = ipcGetTimerEq((TIMER_PTR) timerRef); if (!timer) { X_IPC_MOD_WARNING1("Timer with ref %#x does not exist\n", timerRef); } else { if (timer->status == Timer_In_Use) { /* Need to delay actually deleting the timer in case this function is called from within "ipcTriggerTimers" */ timer->status = Timer_Deleted; } else { ipcDeleteTimer(timer); } } return IPC_OK; } }
/* Check that the format is OK for IPC, and set the "dataHandle" to point to the data (either a byte-array or IPC_VARCONTENT_PTR) to be sent. Last argument added to make this re-entrant, but without need for malloc */ IPC_RETURN_TYPE ipcDataToSend (CONST_FORMAT_PTR format, const char *msgName, unsigned int length, BYTE_ARRAY content, void **dataHandle, IPC_VARCONTENT_PTR varcontent) { FORMAT_CLASS_TYPE formatClass; if (!format) { if (length == 0 || length == IPC_FIXED_LENGTH) { *dataHandle = NULL; return IPC_OK; } else { X_IPC_MOD_WARNING2("Illegal length argument %d for zero-length message\n %s", length, msgName); RETURN_ERROR(IPC_Message_Lengths_Differ); } } else { formatClass = ipcFormatClassType(format); if (formatClass != FixedArrayFMT && formatClass != VarArrayFMT) { X_IPC_MOD_WARNING1("Illegal format for message %s\n", msgName); RETURN_ERROR(IPC_Illegal_Formatter); } else if (!ipcCheckPublishLength(length, format, formatClass)) { X_IPC_MOD_WARNING3("Illegal length argument %d for %s-length message %s\n", length, (formatClass==FixedArrayFMT ? "fixed" : "variable"), msgName); RETURN_ERROR(IPC_Message_Lengths_Differ); } else if (formatClass == FixedArrayFMT) { *dataHandle = content; return IPC_OK; } else { /* VarArrayFMT */ varcontent->length = length; varcontent->content = content; *dataHandle = (void *)varcontent; return IPC_OK; } } }
HND_PTR x_ipc_selfRegisterHnd(int sd, MODULE_PTR hndOrg, HND_DATA_PTR hndData, X_IPC_HND_FN hndProc) { int32 localId; MSG_PTR msg; HND_PTR hnd; HND_KEY_TYPE hndKey; msg = x_ipc_findOrRegisterMessage(hndData->msgName); hndKey.num = sd; hndKey.str = hndData->hndName; LOCK_CM_MUTEX; hnd = GET_HANDLER(&hndKey); UNLOCK_CM_MUTEX; if (!hnd) { hnd = NEW(HND_TYPE); hnd->sd = sd; hnd->localId = 0; hnd->msg = NULL; hnd->hndProc = hndProc; hnd->hndOrg = hndOrg; hnd->hndData = hndData; hnd->msgList = x_ipc_listCreate(); hnd->resource = NULL; hnd->hndLanguage = C_LANGUAGE; /* The default */ #ifdef NMP_IPC hnd->clientData = NO_CLIENT_DATA; hnd->isRegistered = TRUE; #endif LOCK_CM_MUTEX; ADD_HANDLER(&hndKey, hnd); localId = x_ipc_idTableInsert((char *)hnd, GET_C_GLOBAL(hndIdTable)); UNLOCK_CM_MUTEX; hnd->localId = localId; if (hndProc) hnd->hndData->refId = localId; } else { LOCK_M_MUTEX; if (!IS_LISP_MODULE() && hndProc != hnd->hndProc) { /* 24-Jun-91: fedor: the warning is not meaningful for lisp because each re-register will cause a pointer change - lisp functions are not at static locations like c */ X_IPC_MOD_WARNING1("\nWARNING: Procedure change ignored for existing handler %s.\n", hnd->hndData->hndName); } UNLOCK_M_MUTEX; } /* 3-Sep-90: fedor: NULL forces initial module cache of a message. */ hnd->msg = NULL; if (!x_ipc_listMemberItem((char *)hnd, msg->hndList)) x_ipc_listInsertItem((char *)hnd, msg->hndList); if (!x_ipc_listMemberItem((char *)msg, hnd->msgList)) x_ipc_listInsertItem((char *)msg, hnd->msgList); return hnd; }