#include #include #include #include #include #include #include "slices_evt.h" #include "recover.h" #include "utils.h" // Global variable shared by all threads to say "finish current operation and go away" int end=0; WINDOW *winUpdateSliceDump=NULL; static pthread_mutex_t ncursesWriteMutex = PTHREAD_MUTEX_INITIALIZER; struct threadArgs { struct progArgs *progArgs; slices_evt_t *slices; }; void sigHookAbrt() { end=1; } // Main procedures of each thread void *procWorker(void *a); void *procViewer(void *a); int main(int argc, char **argv) { // System structures struct sigaction sa; pthread_t tWorker; // Main data structures slices_evt_t slices; // Progam and threads arguments struct progArgs args; struct threadArgs tArgs; // Algorithmic needs int res, i; // Parse command-line arguments res=parseArgs(argc, argv, &args); if (res!=0) { usage(argv[0]); return 1; } // Set signals behavior memset(&sa,0,sizeof(sa)); sa.sa_handler=sigHookAbrt; res=sigaction(SIGABRT, &sa, NULL); if (res!=0) { return 2; } //XXX Remove srand : only for simulation srand(4); // Data structure initialization // TODO : provides a standard method to do that ? memset(&slices, 0, sizeof(slices)); slices.data=slicesNewSingleton(args.beginSector, args.endSector, S_UNKNOWN); if ( slices.data == NULL ) { return 3; } slices.data->min=args.beginSector; slices.data->max=args.endSector; res=pthread_mutex_init(&(slices.eventListenerMutex), NULL); if (res!=0) { return 4; } // Threads preparation, creation and start memset(&tArgs, 0, sizeof(tArgs)); tArgs.progArgs=&args; tArgs.slices=&slices; res=pthread_create(&tWorker, NULL, procWorker, &tArgs); if (res!=0) { return 5; } // Ncurses interface run in the main thread (void) procViewer((void*)&tArgs); // Thread join point (void) pthread_join(tWorker, NULL); //Final dump of datas address_t blockSize=0; char *dump; dump=slicesDump(slices.data, &blockSize, 1000, args.beginSector, args.endSector); if (dump != NULL) { puts(dump); free(dump); } printf("blockSize==%lld\n", blockSize); printf("slices->count==%d\n", slices.data->count); //Resources desallocation (void) pthread_mutex_destroy(&(slices.eventListenerMutex)); slice_t *curr, *toFree; i=0; curr=slices.data->first; while (curr!=NULL) { i++; toFree=curr; curr=curr->next; free(toFree); } free(slices.data); return 0; } void *procWorker(void *a) { struct threadArgs *tArgs = (struct threadArgs *)a; recover( tArgs->slices, tArgs->progArgs->src, tArgs->progArgs->dst, tArgs->progArgs->ddOpts ); return a; } void cursesUpdateSliceDump(slices_evt_t *slicesEvt, slice_t *modifiedSlice) { // char *strProgress="|/-\\"; // static int progress=0; char *toPrint; address_t blockSize=0; //FIXME : do that realy pthread_mutex_lock(&ncursesWriteMutex); toPrint=slicesDump(slicesEvt->data, &blockSize, 1000, slicesEvt->data->min, slicesEvt->data->max); if (toPrint != NULL) { attron(COLOR_PAIR(4)); mvwprintw(winUpdateSliceDump, 1, 0, toPrint); // attroff(COLOR_PAIR(4)); update_panels(); doupdate(); free(toPrint); } /* sprintf(toPrint, "%c - %p %p", strProgress[progress], slicesEvt, modifiedSlice); progress=(progress+1)%strlen(strProgress); */ pthread_mutex_unlock(&ncursesWriteMutex); } #define CURSESWIN_COUNT 3 void *procViewer(void *a) { WINDOW *wins[CURSESWIN_COUNT]; PANEL *panels[CURSESWIN_COUNT]; int ch, i; char str[2]; struct threadArgs *tArgs = (struct threadArgs *)a; cursesInit(wins, panels, CURSESWIN_COUNT); wattron(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4)); mvwprintw(wins[CURSESWIN_COUNT-1], 1, 0, "(F2 to Exit)"); // wattroff(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4)); update_panels(); doupdate(); /* Enable worker listener */ //FIXME : check pointers ? winUpdateSliceDump=wins[1]; tArgs->slices->eventListener=cursesUpdateSliceDump; while((ch = getch()) != KEY_F(2)) { pthread_mutex_lock(&ncursesWriteMutex); switch(ch) { case '1': case '2': case '3': str[0]=ch; str[1]='\0'; // int (ascii value+flags) to string i=strtol(str, (char **)NULL, 10); // string to real integer if (i>0 && i<=CURSESWIN_COUNT) { top_panel(panels[i-1]); update_panels(); } break; } doupdate(); pthread_mutex_unlock(&ncursesWriteMutex); } pthread_mutex_lock(&(tArgs->slices->eventListenerMutex)); tArgs->slices->eventListener=NULL; pthread_mutex_unlock(&(tArgs->slices->eventListenerMutex)); end=1; cursesUnInit(wins, panels, CURSESWIN_COUNT); return a; }