void SweepAndPrune::updateAxis(unsigned int axis, unsigned int pos, float newval) { auto axisvector = _axis[axis]; if (newval == _axis[axis]->at(pos).value) { //the value has not actually changed, do nothing return; } float oldval = axisvector->at(pos).value; axisvector->at(pos).value = newval; if (newval <= axisvector->at(pos + 1).value && newval >= axisvector->at(pos - 1).value) { //we have changed but we are still in the correct place, //if there are other boxes in our axis we should check against those //to make sure we never skip the last axis checkAndAdd(boxIndex(axisvector->at(pos).box), boxIndex(axisvector->at(pos - 1).box)); checkAndAdd(boxIndex(axisvector->at(pos).box), boxIndex(axisvector->at(pos + 1).box)); return; } if (newval < oldval) { //going down while (newval < axisvector->at(pos-1).value) { swapEndPoints(axis, pos-1, pos); checkAndAdd(boxIndex(axisvector->at(pos).box), boxIndex(axisvector->at(pos-1).box)); pos -= 1; } } else { //going up while (newval > axisvector->at(pos+1).value) { swapEndPoints(axis, pos+1, pos); checkAndAdd(boxIndex(axisvector->at(pos).box), boxIndex(axisvector->at(pos+1).box)); pos += 1; } } }
void *connHandlerThread(void * arg){ //per gestire le situazioni di errore all'interno dei thread, scriviam ouna funzione che chiude gli fd aperti e cancella il record sulla tabella del client di questo thread,e poi il thread muore ritornando struct sockaddr_in clientAddr; struct client *myRecord=(struct client *)(arg); int size=sizeof(clientAddr),ret,i; char *buff=(char *)calloc(100,sizeof(char)); char *logBuff,*bigBuff; //per prima cosa, otteniamo l'ip del client per il quale questo thread gestisce la connessione myRecord->nick=calloc(21,sizeof(char)); myRecord->nome=calloc(21,sizeof(char)); myRecord->cognome=calloc(21,sizeof(char)); myRecord->eta=calloc(3,sizeof(char)); myRecord->ip=calloc(INET_ADDRSTRLEN,sizeof(char)); if(getpeername( myRecord->connSockFd,(struct sockaddr *)&clientAddr,&size )<0){ perror("\n119\n"); data_erase(myRecord); return; } if(inet_ntop(AF_INET,&clientAddr.sin_addr, myRecord->ip,INET_ADDRSTRLEN)==NULL){ perror("\n124\n"); data_erase(myRecord); return; } //abbiamo ip del client, e scriviamo un log che dice che quell'ip si e' connesso logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,LOGGEDNOIDENT); add_log( logBuff); while(1){ ret=read(myRecord->connSockFd,buff,100); //IMPLEMENTA LA FULL READ!!!!!!!!! if(ret<0){ perror("\n151\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_READING); add_log( logBuff); data_erase(myRecord); return; } else if(ret==0){ //il client ci ha mandato FIN per disconnettersi printf("\nClient disconnesso!\n"); fflush(stdout); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,DISCONNECTED); add_log( logBuff ); data_erase(myRecord); return; } else{ //allora abbiamo letto normalmente, quindi controlliamo il codice (di protocollo) del messaggio ricevuto if(buff[0]==3){ //il client ci sta mandando i suoi dati //tiriamo fuori (secondo il protocollo) i vari dati inviatici dal client e ce li salviamo nella struct globale dei client strncpy( myRecord->nick,buff+1,20 ); myRecord->nick[20]='\0'; strncpy( myRecord->nome,buff+21,20); myRecord->nome[20]='\0'; strncpy( myRecord->cognome,buff+41,20); myRecord->cognome[20]='\0'; strncpy( myRecord->eta,buff+61,2); myRecord->eta[2]='\0'; //e concateniamo le varie stringhe per creare un messaggio da scrivere nel log file che indichi che l'utente che si era connesso prima con quel dato ip, ora ha fornito i dati identificativi logBuff=(char *)calloc(100,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,"is> "); strcat(logBuff,myRecord->nick); strcat(logBuff,myRecord->nome); strcat(logBuff,myRecord->cognome); strcat(logBuff,myRecord->eta); strcat(logBuff,"\n"); add_log(logBuff); //ora che siamo identificati da un nick, possiamo scaricare verso il client che stiamo gestendo, tutti i messaggi relativi alle vecchie segnalazioni gestite //accediamo quindi alla tabNotifiche sotto mutex4 pthread_mutex_lock(&mutex4); for(i=0;i<MAX_NOTIFICHE;i++){ if(tabNotifiche[i].nomeDest==NULL) break; if( !strncmp(myRecord->nome,tabNotifiche[i].nomeDest,20) && !strncmp(myRecord->cognome,tabNotifiche[i].cognomeDest,20) && !strncmp(myRecord->nick,tabNotifiche[i].nickDest,20) && !strncmp(myRecord->eta,tabNotifiche[i].etaDest,20) ) //allora c'e' corrispondenzza, e inviamo la notifica al client che stiamo gestendo if(write(myRecord->connSockFd,tabNotifiche[i].messaggio,strlen(tabNotifiche[i].messaggio)+1)<0){ pthread_mutex_unlock(&mutex4); perror("\n213\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,ABORT); add_log( logBuff); data_erase(myRecord); return; } } pthread_mutex_unlock(&mutex4); } else if(buff[0]==1){ //il client vuole vedere la lista delle segnalazioni, quindi facciamo lock del mutex1, spostiamo il puntatore al file delle buche all'inizio, leggiamo tutto il file, rilasciamo lock e inviamo il tutto al client bigBuff=(char *)calloc(1000,sizeof(char)); pthread_mutex_lock(&mutex1); lseek(fdBucheFile,0,SEEK_SET); ret=0; while((ret=read(fdBucheFile,bigBuff+strlen(bigBuff),100))>0); //inviamolo al client if(ret<0){ pthread_mutex_unlock(&mutex1); perror("\n234\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_READING); add_log( logBuff); data_erase(myRecord); return; } pthread_mutex_unlock(&mutex1); if(write(myRecord->connSockFd,bigBuff,strlen(bigBuff))<0){ perror("\n242\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_WRITING); add_log( logBuff); data_erase(myRecord); return; } //se siamo arrivati qui vuol dire che siamo riusciti a mandare al client il contenuto del file //con tutte le buche salvate //quindi ricominciamo continue; } else if(buff[0]==2){ //allora il client ci sta inviando i dati per una nuova segnalazione //per prima cosa li tiriamo fuori char *riferimento,*x,*y; riferimento=(char *)calloc(21,sizeof(char)); x=(char *)calloc(4,sizeof(char)); y=(char *)calloc(4,sizeof(char)); strncpy(riferimento,buff+1,20); riferimento[20]='\0'; strncpy(x,buff+21,3); x[3]='\0'; strncpy(y,buff+24,3); y[3]='\0'; int check; //poi li passiamo ad una funzione che si occupa di vedere se ci sono nel file delle buche (accede in mutex1)gia' 2 segnalazioni nelle vicinanze, e in quel caso rilascia mutex1 e ritorna 0, non aggiungendo la segnalazione, ma si occupera' di A) cambiare lo stato delle 2 segnalazioni gia' presenti (xke' vuol dire che con la terza segn arrivata abbiamo avviato un'opera di gestione) B) mettere le notifiche nella tabNotifiche che verranno consegnate ai 2 utenti che avevano fatto quella segnalazione, e noi scriveremo direttamente adesso sul socket del client che non e' stata gestita la sua segnalazione xke' invece grazie a lui e' stata avviata opera di gestione. In caso invece non ci siano gia' 2 segnalaz nel file etc, la funzione la aggiunge e stop, e ritorna 1, e noi avvisiamo il client if((check=checkAndAdd(myRecord,riferimento,x,y))==0){ //la funz ha ritornato 0, quindi ci sono gia' //2 segnalazioni nel file nelle vicinanze di quel riferimento, quindi //non abbiamo creato la segnalazione nel file(e quindi lo diciamo al client) ma abbiamo avviato gestione (la funzione si e' occupata di //cambiare lo stato di quelle buche e mettere nella tabNotifiche le notifiche relative ai segnalatori). Noi dobbiamo quindi avvisare //soltanto il client if(write(myRecord->connSockFd,FEEDBACK1,64)<0){ perror("\n242\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_WRITING); add_log( logBuff); data_erase(myRecord); return; } } else if(check==1){ //in questo caso la funzione checkAndAdd ha ritornato 1, quindi la segnalazione e' stata normalmente aggiunta! Confermiamo al client if(write(myRecord->connSockFd,FEEDBACK2,34)<0) { perror("\n242\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_WRITING); add_log( logBuff); data_erase(myRecord); return; } } else if(check<0){ //la funzione non e' riuscita a scrivere sul file, avvisiamo il client if(write(myRecord->connSockFd,FEEDBACK3,58)<0) { perror("\n242\n"); logBuff=(char *)calloc(50,sizeof(char)); strcpy(logBuff,myRecord->ip); strcat(logBuff,E_WRITING); add_log( logBuff); data_erase(myRecord); return; } } else if(buff[0]==3){ } } } } void data_erase(struct client *myRecord ){ pthread_mutex_lock(&mutex3); close(myRecord->connSockFd); myRecord->connSockFd=0; free(myRecord->nome); free(myRecord->cognome); free(myRecord->nick); free(myRecord->ip); free(myRecord->eta); pthread_mutex_unlock(&mutex3); }