address addrPrec(address ad, addressSet circuit){ int i=addrToRank(ad); if (i==(-1)) { ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE,__FILE__,__LINE__,"addr not found"); } do { i=(i+NP-1) % NP; } while (!addrIsMember(rankToAddr(i), circuit)); return rankToAddr(i); }
womim * receive(trComm * aComm){ womim * msgExt; int nbRead, nbRead2; int length; int j; bool isPred; nbRead = commReadFully(aComm, &length, sizeof(length)); if (nbRead == sizeof(length)) { msgExt = calloc(length + sizeof(prefix), sizeof(char)); assert(msgExt != NULL); nbRead2 = commReadFully(aComm, ((char*) msgExt) + sizeof(prefix) + nbRead, (length - nbRead)); if (nbRead2 == length - nbRead) { pthread_mutex_init(&(msgExt->pfx.mutex), NULL ); msgExt->pfx.counter = 1; msgExt->msg.len = length; return (msgExt); } else { free(msgExt); } } //Connection has been closed //search the address which has vanished searchTComm(aComm, globalAddrArray, &j, &isPred); if (j == -1) { // It may happen when automaton has closed all the connections (thus // has erased aComm from globalAddrArray). As we are already aware of // this connection loss, there is nothing to do. return NULL ; } //create the DISCONNECT to return MType disconnectType; if (isPred) { disconnectType = DISCONNECT_PRED; } else { disconnectType = DISCONNECT_SUCC; } msgExt = calloc( sizeof(prefix) + sizeof(newMsg(disconnectType, rankToAddr(j))), sizeof(char)); pthread_mutex_init(&(msgExt->pfx.mutex), NULL ); msgExt->pfx.counter = 1; msgExt->msg = newMsg(disconnectType, rankToAddr(j)); //close the connection closeConnection(rankToAddr(j), isPred); return (msgExt); }
int main() { addressSet arrivedSet; addressSet goneSet; compare("addrIsNull", addrIsNull(nullAddress), true); compare("addrIsNull", addrIsNull(myAddress), false); compare("addrCmp", addrCmp(nullAddress,myAddress), true); compare("addrCmp", addrCmp(myAddress,nullAddress), false); compare("addrIsEqual", addrIsEqual(nullAddress,nullAddress), true); compare("addrIsEqual", addrIsEqual(myAddress,nullAddress), false); compare("addrIsMine", addrIsMine(myAddress), true); compare("addrIsMine", addrIsMine(nullAddress), false); printf("Testing %s...", "addr_2_str"); addrToStr(s,myAddress); if (strcmp(s, "#00") != 0){ printf("... KO (s is \"%s\" instead of \"%s\")\n", s, "#00"); exit(EXIT_FAILURE); } printf("...OK\n"); compare("addrToRank", addrToRank(myAddress), 0); compare("addrToRank", addrToRank(0x8000), 15); compare("addrToRank", addrToRank(nullAddress), -1); compare("rankToAddr", rankToAddr(0), myAddress); compare("rankToAddr", rankToAddr(15), 0x8000); compare("rankToAddr", rankToAddr(16), nullAddress); compare("addrIsMember", addrIsMember(myAddress, 0xFFFF), true); compare("addrIsMember", addrIsMember(myAddress, 0xFFFE), false); arrivedSet = 0xFFFE; addrAppendArrived(&arrivedSet, myAddress); compare("addrAppendArrived", arrivedSet, 0xFFFF); arrivedSet = 0x0000; addrAppendArrived(&arrivedSet, myAddress); compare("addrAppendArrived", arrivedSet, 0x0001); arrivedSet = 0x0000; goneSet = 0xFFFE; addrAppendGone(&arrivedSet, &goneSet, myAddress); printf("Testing %s...", "addr_appendGone"); if ((arrivedSet != 0x0000) || (goneSet != 0xFFFF)){ printf("... KO (arrivedSet is \"%d\" instead of \"%d\" OR goneSet is \"%d\" instead of \"%d\")\n", arrivedSet, 0x0000, goneSet, 0xFFFF); exit(EXIT_FAILURE); } printf("...OK\n"); arrivedSet = 0xFFFF; goneSet = 0x0000; addrAppendGone(&arrivedSet, &goneSet, myAddress); printf("Testing %s...", "addr_appendGone"); if ((arrivedSet != 0xFFFE) || (goneSet != 0x0000)){ printf("... KO (arrivedSet is \"%d\" instead of \"%d\" OR goneSet is \"%d\" instead of \"%d\")\n", arrivedSet, 0xFFFF, goneSet, 0x0000); exit(EXIT_FAILURE); } printf("...OK\n"); compare("addrUpdateCircuit", addrUpdateCircuit(0xFFFF, myAddress, 0xFF00, 0x00FF), 0xFF00); compare("addrPrec", addrPrec(0x8000, 0x8000|0x0001), 0x0001); compare("addrPrec", addrPrec(0x0001, 0x8000|0x0001), 0x8000); return EXIT_SUCCESS; }
/** * @brief Initialization of trains protocol middleware * @param[in] trainsNumber The number of trains on the circuit * @param[in] wagonLength The length of the wagons in the trains * @param[in] waitNb The number of time to wait * @param[in] waitTime The time to wait (in microsecond) * @param[in] callbackCircuitChange Function to be called when there is a circuit changed (Arrival or departure of a process) * @param[in] callbackUtoDeliver Function to be called when a message can be uto-delivered by trains protocol * @return 0 upon successful completion, or -1 if an error occurred (in which case, @a trErrno is set appropriately) */ int trInit(int trainsNumber, int wagonLength, int waitNb, int waitTime, CallbackCircuitChange callbackCircuitChange, CallbackUtoDeliver callbackUtoDeliver){ int rc; pthread_t thread; char trainsHost[1024]; char *trainsPort; int rank; if (trainsNumber > 0) ntr = trainsNumber; if (wagonLength > 0) wagonMaxLen = wagonLength; if(waitNb > 0) waitNbMax = waitNb; if (waitTime > 0) waitDefaultTime = waitTime; rc = sem_init(&sem_init_done,0,0); if(rc) error_at_line(EXIT_FAILURE, rc, __FILE__, __LINE__, "sem_init"); rc= pthread_cond_init(&condWagonToSend, NULL); assert(rc == 0); theCallbackCircuitChange = callbackCircuitChange; theCallbackUtoDeliver = callbackUtoDeliver; globalAddrArray = addrGenerator(LOCALISATION, NP); rc = gethostname(trainsHost,1024); if(rc != 0){ error_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "Error getting hostname"); } trainsPort = getenv("TRAINS_PORT"); if (trainsPort == NULL) error_at_line(EXIT_FAILURE,0,__FILE__,__LINE__,"TRAINS_PORT environment variable is not defined"); rank = addrID(trainsHost,trainsPort,globalAddrArray); if (rank < 0) error_at_line(EXIT_FAILURE,0,__FILE__,__LINE__,"Could not find a line in %s file corresponding to TRAINS_HOST environment variable value (%s) and TRAINS_PORT environment variable value (%s)", LOCALISATION, trainsHost, trainsPort); myAddress=rankToAddr(rank); automatonInit(); do { rc = sem_wait(&sem_init_done); } while ((rc < 0) && (errno == EINTR)); if (rc) error_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "sem_wait()"); rc = pthread_create(&thread, NULL, utoDeliveries, NULL); if (rc) error_at_line(EXIT_FAILURE, rc, __FILE__, __LINE__, "pthread_create"); rc = pthread_detach(thread); if (rc) error_at_line(EXIT_FAILURE, rc, __FILE__, __LINE__, "pthread_detach"); return 0; }