LCOV - code coverage report
Current view: top level - imp - main.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 128 184 69.6 %
Date: 2025-11-11 12:26:46 Functions: 7 7 100.0 %

          Line data    Source code
       1             : #include "../inc/header.h"
       2             : #include "../inc/param_manager.h"
       3             : #include "../inc/global_param.h"
       4             : #include "../inc/utils.h"
       5             : #include "../inc/query_manager.h"
       6             : #include "../inc/save_manager.h"
       7             : #include <string> 
       8             : #include <sstream>
       9             : #include <vector>
      10             : #include <iterator>
      11             : 
      12             : 
      13             : 
      14             : GlobalParam GlobalParam::instance_ = GlobalParam();
      15             : 
      16             : /**
      17             :  *  \file main.cu
      18             :  *  \author martigan moilerat
      19             :  *  \brief Fichier d entrée du programme
      20             :  *  \fn int main(int argc, char **argv)
      21             :  *  \def query_type
      22             :  *  \fn void sig_handler(int signo)
      23             :  */
      24             : 
      25             : #include <map>
      26             : #include <iostream>
      27             : #include <sstream>
      28             : #include <algorithm>
      29             : 
      30             : 
      31             : #include <fstream>
      32             : 
      33             : /*
      34             :  compilation :
      35             :  nvcc -g main.cu gpu.cu server.cu file.cu  -o fvs
      36             :  =>
      37             :  use make instead of this
      38             :  gcc -g  main.cu server.cu file.cu utils.cu -DONLY_CPU -o fvs
      39             :  x86_64-linux-gnu-gcc -g main.cu -DONLY_CPU -o fvs
      40             :  execution :
      41             :  gdb fvs  run  quand ca plante :   bt
      42             :  -
      43             :  ou bien
      44             :  fvs puis quand ca plante
      45             :  gdb fvs core et bt
      46             : 
      47             :  //si bt ne donne rien sortir avec quit puis
      48             :  ulimit -c unlimited
      49             :  // et reexecuter
      50             : 
      51             :  valgrind dans un fichier :
      52             :  valgrind --leak-check=full --show-leak-kinds=all ./fvs P3333 R/home/fotonower/workarea/temp_0606/ A$PWD/fvs_conf_26_15.ini > file.txt 2>&1
      53             : 
      54             :  pour debugger avec valgrind :
      55             :  valgrind --leak-check=full --show-leak-kinds=all --vgdb=yes --vgdb-error=0 ./fvs P3333 R/home/fotonower/workarea/temp_0606/ A$PWD/fvs_conf_26_15.ini
      56             :  gdb -args ./fvs P3333 A$PWD/fvs_conf_26_15.ini R/home/fotonower/workarea/temp_0606/
      57             :  dans gdb target remote | vgdb
      58             :  puis set breakpoints
      59             :  puis c
      60             :  dans gdb le leak check est accesssible :
      61             : 
      62             :  monitor leak_check full reachable any
      63             :  */
      64             : 
      65             : #define COMPARE(x,y)   ((x)<(y)?0:1)
      66             : 
      67             : 
      68             : /*
      69             : int saveOnExitWithSomeTry(std::vector<int> &indexCurrent, int verbose)
      70             : {
      71             :     GlobalParam &gp = GlobalParam::Instance();
      72             :     for (int i = 0; i < gp.nbtype_; ++i)
      73             :     {
      74             :         int prevIndexCurrent = indexCurrent.at(i);
      75             :         if (indexCurrent.at(i) == 0)
      76             :             continue;
      77             :         indexCurrent.at(i) = (indexCurrent.at(i) > INSERT ? 0 : indexCurrent.at(i));
      78             :         printf("About to insert : %d, %d\n", indexCurrent.at(i), INSERT);
      79             :         int token = getTokenWriteIndex(GlobalParam::Instance().pid_, gp.WriteCache[i][0].dire);
      80             :         int nb_try = 20;
      81             :         int count_try = 0;
      82             :         while (token != -1 && count_try < nb_try)
      83             :         {
      84             :             if (count_try == nb_try)
      85             :             {
      86             :                 printf("Token on index is used, we stopped without saving this amount of data : %d\n", prevIndexCurrent);
      87             :                 return 1;
      88             :             }
      89             :             usleep(10);
      90             :             token = getTokenWriteIndex(GlobalParam::Instance().pid_, gp.WriteCache[i][0].dire);
      91             :             count_try++;
      92             :         }
      93             :         save(gp.WriteCache[i][0].dire, GlobalParam::Instance().filename_photo_id_list_str_, gp.WriteCache[i], gp.WriteCache[i][0].dire, indexCurrent.at(i), verbose);
      94             :         giveBackToken(gp.WriteCache[i][0].dire);
      95             :     }
      96             :     return 0;
      97             : }*/
      98             : 
      99           2 : int configureParamFromArgAndPrintHelp(LocalParam & lp, int argc, char **argv)
     100             : {
     101          11 :     for (int i = 0; i < argc; ++i)
     102             :     {
     103           9 :         if (argv[i][0] == 'L')
     104             :         {
     105           0 :             lp.limit_data = atoi(&argv[i][1]);
     106           0 :             lp.empty_server = lp.limit_data == 0;
     107             :         }
     108           9 :         if (argv[i][0] == 'P')
     109             :         {
     110           1 :             GlobalParam::Instance().port_ = atoi(&argv[i][1]);
     111             :         }
     112           9 :         if (argv[i][0] == 'C')
     113           1 :             lp.cleaning_data = 1;
     114           9 :         if (argv[i][0] == 'R')
     115             :             // pourquoi est-ce qu'on ne convertit pas en std::string ce truc la ?
     116           2 :             GlobalParam::Instance().velours_std_ += &argv[i][1];
     117           9 :         if (argv[i][0] == 'T')
     118           2 :                         if(atoi(&argv[i][1])<-1)
     119           0 :                                 lp.desc_type_dyn = atoi(&argv[i][1]);
     120             :                         else
     121           2 :                                 lp.descriptor_type = atoi(&argv[i][1]);
     122           9 :         if (argv[i][0] == 'F')
     123           0 :             lp.cleanCPU = 1;
     124           9 :         if (argv[i][0] == 'A')
     125             :         {
     126           1 :             char *conf_file = &argv[i][1];
     127           1 :             lp.conf_file = std::string(conf_file);
     128             :         }
     129           9 :         if (argv[i][0] == 'S')
     130           0 :             lp.insert_save_file = 0;
     131           9 :         if (argv[i][0] == 'N')
     132           0 :             lp.insert_sync_cache = 0;
     133           9 :         if (argv[i][0] == 'v')
     134           0 :             lp.verbose = 1;
     135           9 :         if (argv[i][0] == 'O')
     136           0 :             lp.load_only_main = 1;
     137           9 :         if (argv[i][0] == 'D')
     138             :         {
     139           0 :             GlobalParam::Instance().dontCheckDuplicateIdObject_ = true;
     140             :         }
     141           9 :         if (argv[i][0] == 'H' || argv[i][0] == 'h')
     142             :         {
     143           0 :             puts("help : arguments are \n LX to limit data loading where X is number\n PX to set the port for socket where X is number\n C to clean datas and exit afterwards\n RX to set datas path where X is path\n TX to set a particular data type for server where X is number\n F to set variable cleanCPU \n AX to set server with configuration file where X is path/to/conf_file\n v for verbose mode\n O to set load_only_main (wtf ?)\n ");
     144           0 :             puts("D to avoid checking duplicate entry of id objcet when writing the files after insertion (should increase speed by 10000)\n hH To display this help \n List of possible arguments : LPCRTFAvODHh\n S not save in file \n N not load in cache\n");
     145           0 :             return 1;
     146             :         }
     147             :     }
     148             :     return 0;
     149             : }
     150             : 
     151             : 
     152           2 : int InitWriteCache(GlobalParam & gp, LocalParam & lp, std::vector<std::vector<to_insert_t> > & WriteCache)
     153             : {
     154             :     // VR 4-11-16 a mettre dans
     155           2 :     lp.ReadCacheCPU.resize(gp.nbtype_);
     156           2 :     if (lp.verbose)
     157             :     {
     158           0 :         printf("M alloc struct for insertion of datas %d\n", INSERT_MAX);
     159           0 :         printf("gp.WriteCache will be allocated, current size : %ld \n", (gp.WriteCache.size()));
     160             :     }
     161           2 :     if (lp.ReadCacheCPU.size() == 0)
     162             :     {
     163           0 :         printf("ERROR &(ReadCacheCPU.size()) is of size empty %ld : \n", (lp.ReadCacheCPU.size()));
     164           0 :         puts("ERROR, we had bette to stop this !");
     165             :     }
     166           2 :     gp.WriteCache.resize(gp.nbtype_);
     167          12 :     for (int i = 0; i < gp.WriteCache.size(); i++)
     168             :     {
     169          10 :         gp.WriteCache[i].resize(INSERT_MAX);
     170             :     }
     171             : 
     172           2 :     if (lp.verbose)
     173           0 :         printf("gp.WriteCache has been allocated : current size %ld\n", gp.WriteCache.size());
     174           2 :     gp.indexCurrent.resize(gp.nbtype_);
     175           2 :     lp.indexCurrent.resize(gp.nbtype_);
     176           2 :     std::fill(gp.indexCurrent.begin(), gp.indexCurrent.end(), 0);
     177           2 :     std::fill(lp.indexCurrent.begin(), lp.indexCurrent.end(), 0);
     178          12 :     for (int i = 0; i < lp.ReadCacheCPU.size(); ++i)
     179             :     {
     180          10 :         if (lp.verbose)
     181           0 :             printf("ReadCacheCPU[%d].size = %u\n", i, lp.ReadCacheCPU[i].size);
     182             : 
     183          10 :         gp.WriteCache[i].resize(INSERT_MAX);
     184             :     }
     185           2 :     return 0;
     186             : }
     187             : 
     188             : 
     189             : 
     190           2 : int setCacheParamWhenNoDataLoaded(std::vector<types_datas_t> & ReadCacheCPU, GlobalParam & gp, LocalParam & lp)
     191             : {
     192           2 :     lp.dimension = ReadCacheCPU[0].size;
     193           2 :     std::cout<<"in No data loaded settings "<<std::endl;
     194          12 :     for (int i = 0; i < ReadCacheCPU.size(); ++i)
     195             :     {
     196             :         // VR 3-11-16 : je suis tres etonné par cela, au moins dans l'autre sens et puis de toute facon cela a l'air farfelu
     197          10 :         lp.dimension = (lp.dimension < ReadCacheCPU[i].size ? ReadCacheCPU[i].size : lp.dimension);
     198          10 :         if (ReadCacheCPU[i].size != 0)
     199           9 :             ReadCacheCPU[i].resizeDatas(ReadCacheCPU[i].datas_vec.size() / ReadCacheCPU[i].size);
     200             : 
     201             :         // Cette partie me parait un tout petit peu plus raisonnable mais je prefererai que ce soit fait dans commitInsert
     202          10 :         if (lp.nb_data_in_file == 0)
     203             :         {
     204           9 :             ReadCacheCPU[i].nb_max_data = SIZE_ALLOCATION_BUFFER / 10;
     205             : 
     206             :             // VR TODO weird 26-9-16
     207           9 :             ReadCacheCPU[i].resizeDatas(ReadCacheCPU[i].nb_max_data);
     208             :         }
     209             :     }
     210             :     
     211             :     //std::cout<<"ReadCache size : "<<ReadCacheCPU[0].nb_max_data<<std::endl;
     212             : 
     213           2 :     if (lp.verbose)
     214           0 :         printf("gp.WriteCache size after load data %ld \n", gp.WriteCache.size());
     215           2 :     return 0;
     216             : }
     217             : 
     218           2 : void initFolderDataLocation(GlobalParam &gp, LocalParam &lp)
     219             : {
     220             :         /**
     221             :          * Initialise le chemin vers le dossier des descripteurs dans GeneralParam
     222             :          */ 
     223             :     // VR 26-9-16  std::string buildFolder(std::string local_folder)
     224           2 :     if (gp.velours_std_.size() == 0)
     225             :     {
     226             :         // MG 4-11-16 : il n'y a pas de fonction c++ getenv
     227             :         // VR 4-11-16 : l'absence de preuve n'est pas la preuve de l'absence
     228             :         // VR 4-11-16 : tu peux la faire
     229             :         // remove pointer, VR 13-10-16 : je ne sais pas trop comment tester cette ligne
     230           0 :         char * env_aux = getenv(gp.velours_root_env_name_.c_str());
     231           0 :         if (env_aux)
     232           0 :             gp.velours_std_ += env_aux;
     233           0 :         std::cout<<" Affichage de la var environnement Velours_Root_2"<<std::endl;
     234           0 :         if (!gp.velours_std_.size())
     235             :         {
     236           0 :             std::cout << "Please set env var VELOURS_ROOT_2, or pass argument R/path/to/binaryfolders\n";
     237           0 :             std::cout << "Aborting launch\n";
     238           0 :             exit(1);
     239             :         }
     240           0 :         if (lp.descriptor_type != -1)
     241             :         {
     242           0 :             if (gp.velours_std_[gp.velours_std_.size() - 1] != '/')
     243             :             {
     244           0 :                 gp.velours_std_ += "/";
     245             :             }
     246           0 :             gp.velours_std_ += "binary";
     247           0 :             gp.velours_std_ += boost::lexical_cast<std::string>(lp.descriptor_type);
     248             :         }
     249             :     }
     250           2 :     if (gp.velours_std_[gp.velours_std_.size() - 1] != '/')
     251             :     {
     252           1 :         gp.velours_std_ += "/";
     253             :     }
     254           2 :     std::cout<<"path to binary : "<<gp.velours_std_<<std::endl;
     255           2 : }
     256             : 
     257             : 
     258             : // Initialisation du supporteed_type_vec je dois modifie cette fonction car var globale a supprimer
     259           2 : int configureTypeAvailable(GlobalParam &gp, LocalParam &lp)
     260             : {
     261             :         /**
     262             :          * initialise le desc type dans LocalParam  
     263             :          */ 
     264             : 
     265           2 :     if (gp.port_ == 0 && (lp.cleaning_data == 0))
     266             :     {
     267           0 :         puts("wrong port argument, exiting");
     268           0 :         exit(1);
     269             :     }
     270             :     
     271           2 :     std::cout<<"ConfTypeAvail args : port "<< gp.port_<<" cleaning "<<lp.cleaning_data<<std::endl;
     272           2 :     if (lp.conf_file != "")
     273             :     {
     274             :                 // chargement du conf file pour recuperer les desc type (initialisation des supported_vec)
     275           1 :         int ret = set_with_conf_file(lp.conf_file,gp,lp);
     276           1 :         if (ret == 1)
     277             :         {
     278           0 :             std::cout << "Returning non 0 status while reading conf_file : " << lp.conf_file << std::endl;
     279           0 :             return 1;
     280             :         }
     281             :     }
     282             :     else
     283             :     {
     284           1 :         setdefault(gp,lp);
     285             :     }
     286           2 :     if (lp.descriptor_type != -1)
     287             :     {
     288           2 :                 std::cout<<"desc type in local "<<lp.descriptor_type<<std::endl;
     289           2 :         int type_it = FindDescIndex(lp.ReadCacheCPU, lp.descriptor_type);
     290           2 :         if (type_it == -1){
     291           0 :             puts("type not in conf file");
     292           0 :             return 3;
     293             :         }
     294             :     }
     295             : 
     296             :     return 0;
     297             : }
     298             : 
     299           2 : int init(LocalParam & lp, int argc = 0, char **argv = NULL)
     300             : {
     301           2 :     GlobalParam &gp = GlobalParam::Instance();
     302             : 
     303             :     // VR 6-11-16 : il faut utiliser ceci avec intelligence dans un souci de clarté
     304           2 :     std::vector<types_datas_t> & ReadCacheCPU = lp.ReadCacheCPU;
     305             : 
     306           2 :     int ret = configureParamFromArgAndPrintHelp(lp, argc, argv);
     307           2 :     if (ret != 0)
     308             :         return ret;
     309             :         
     310             : 
     311           2 :     if (lp.verbose)
     312           0 :         printf("gp.WriteCache size before get env %ld \n", (gp.WriteCache.size()));
     313             : 
     314             :     // VR 4-11-16 : fonction d'initialisation de dossier de données
     315           2 :     initFolderDataLocation(gp, lp);
     316             : 
     317           2 :     if (lp.verbose)
     318           0 :         printf("gp.WriteCache size after checking velours_root %ld \n", (gp.WriteCache.size()));
     319             : 
     320           2 :     std::cout << " lp.insert_save_file : " << lp.insert_save_file<< " lp.insert_sync_cache : "<<lp.insert_sync_cache << std::endl;
     321           2 :     puts("");
     322             : 
     323             :     // VR 26-9-16 void configureTypeAvailable()
     324           2 :     ret = configureTypeAvailable(gp, lp);
     325           2 :     if (ret != 0)
     326             :         return ret;
     327           2 :     printf("Nb Data in Search Engine before WriteCache data: %d\n",lp.nb_data_in_file);
     328             : 
     329           2 :     InitWriteCache(gp, lp, gp.WriteCache);
     330             :     
     331           2 :     printf("Nb Data in Search Engine before loading data: %d\n", lp.nb_data_in_file);
     332             : 
     333             :     // VR 5-11-16 Il faut passer a cette fonction les memes arguments que setCacheParamAMoitie pour les mettre ensemble
     334           2 :         ret = LoadDataInCache(gp, lp, lp.descriptor_type, lp.verbose, gp.velours_std_, 0, lp.cleaning_data);
     335           2 :         if (ret != 0)
     336             :         {
     337           0 :                         std::cout << " LoadDataInCache return non 0 status " << std::endl;
     338           0 :                         return ret;
     339             :         }
     340             :     
     341             : 
     342             :     // VR 4-11-16 On voudrait virer tout ce bout la ou le mettre dans le setCacheParam
     343             :     // la dedans on initialise ReadCacheCPU lorsqu'il n'y a pas de données et on fais quelquechose d'autres, mais on pourrait faire cela dans commitInsert eventuellement
     344           2 :     setCacheParamWhenNoDataLoaded(ReadCacheCPU, gp, lp);
     345             : 
     346             :     //------------------------------------------------------------------------------
     347           2 :     printf("Nb Data in Search Engine : %d\n", lp.nb_data_in_file);
     348           2 :     printf("limit_return : %d\n", LIMIT_RETURN);
     349             : 
     350             :     // mettre la suite dans cette fonction bloque les tests, y aurait-il un os ici ?
     351             : 
     352             : 
     353             :     // pour plus avoir les datas_vec en CPU
     354           2 :     if (lp.cleanCPU)
     355             :     {
     356             :         // void fonction cleanCPUData(ReadCacheCPU) quand on veut
     357           0 :         for (int i = 0; i < gp.nbtype_; ++i)
     358             :         {
     359           0 :             ReadCacheCPU[i].resizeDatas(ReadCacheCPU[i].nb_data);
     360             :         }
     361             :     }
     362           2 :     std::cout<<"Init RC size : "<<ReadCacheCPU[0].datas_vec.size()<<std::endl;
     363             :     ////////////// fin lecture données ///////////////////
     364             : 
     365             : 
     366             :     // VR 6-11-16 : je serais tenter de faire cela seulement avant le remplissage, et pas trop content de cette variable global SIZE_ALLOCATION_BUFFER
     367             :     // VR 6-11-16 : il faut comenter la ligne suivante, mais cela casse les tests
     368           2 :     lp.idc_vec.resize(lp.nb_data_in_file + SIZE_ALLOCATION_BUFFER);
     369             : 
     370           2 :     gp.sock_ = create_server(GlobalParam::Instance().port_);
     371           2 :     if (gp.sock_ == -1)
     372             :     {
     373           0 :         puts("error opening socket\n");
     374           0 :         return 3;
     375             :     }
     376             : 
     377           2 :     if (lp.cleaning_data > 0)
     378             :     {
     379           1 :                 puts("start cleaning data");
     380           1 :         exit(cleanTokenProof(gp, lp));
     381             :     }
     382             : 
     383           1 :     puts("end initialisation\n");
     384           1 :     if (lp.verbose)
     385           1 :         printf("gp.WriteCache size after begin while %ld \n", gp.WriteCache.size());
     386             : 
     387             :     return 0;
     388             : }
     389             : 
     390             : 
     391             : 
     392           2 : int main(int argc, char **argv)
     393             : {
     394             : 
     395             :     // VR 12-10-16 : la prochaine de refacto etape sera d'enlever le plus de variable global possible
     396           2 :     GlobalParam &gp = GlobalParam::Instance();
     397           2 :     LocalParam lp;
     398           2 :         printf("lp.nb_data_in_file : %d\n",lp.nb_data_in_file);
     399             :         
     400             : #ifndef ONLY_CPU
     401             :         int nDevices;
     402             : 
     403             :         cudaGetDeviceCount(&nDevices);
     404             :         
     405             :         std::cout<<"nb devices : "<<nDevices<<std::endl;
     406             :         for (int i = 0; i < nDevices; i++){
     407             :     cudaDeviceProp prop;
     408             :     cudaGetDeviceProperties(&prop, i);
     409             :     printf("Device Number: %d\n", i);
     410             :     printf("  Device name: %s\n", prop.name);
     411             :     printf("  Memory Clock Rate (KHz): %d\n",
     412             :            prop.memoryClockRate);
     413             :     printf("  Memory Bus Width (bits): %d\n",
     414             :            prop.memoryBusWidth);
     415             :     printf("  Peak Memory Bandwidth (GB/s): %f\n\n",
     416             :            2.0*prop.memoryClockRate*(prop.memoryBusWidth/8)/1.0e6);
     417             :    }
     418             : #endif
     419             : 
     420             :     // MG 13/07/16 : need to test with mapped memory for distance transfert : not sure if we will gain much time, we may loose some actually => VR 4-11-16 : je crois que Lokmane l'a fait, non ?
     421             : 
     422             :     //------------------------------------------------------------------------------
     423             :     // VR 4-11-16 : fonction d'initialisation
     424           2 :     if (0 != init(lp, argc, argv))
     425             :         return 1;
     426             : 
     427           1 :     Query & cur_query = lp.query;
     428           1 :     std::cout<<" Start main while loop, cleaning_data : "<<lp.cleaning_data<<std::endl;
     429          14 :     clock_t timer;
     430          14 :     while (true)
     431             :     {
     432          14 :         displayTime(timer);
     433          14 :                 lp.cs = createConnectionAndOutputIp(gp.sock_);
     434          14 :                 printf(" lp.cs %d, gp.sock_ %d, gp.port_ %d \n",lp.cs,gp.sock_, gp.port_);
     435          14 :         displayTime(timer, "Got Connection");
     436          14 :                 lp.retval_set_query = cur_query.load_query(lp.cs, lp.descriptor_type, lp, lp.verbose);
     437          14 :         displayTime(timer, "Query loaded");
     438          14 :                 std::cout<<"photo desc : "  << lp.descriptor_type <<std::endl;
     439          14 :                 if (lp.retval_set_query == 0)
     440             :         {
     441          14 :                      std::cout<<"avant executeQuery"<<std::endl;
     442          14 :             int rete = executeQuery(cur_query, lp, gp);
     443          14 :             displayTime(timer, "Query executed ! ");
     444          14 :             if (rete != 0)
     445             :             {
     446           9 :                 if (rete == 100)
     447             :                     break;
     448           8 :                 if (rete == 101)
     449           8 :                     continue;
     450             : 
     451           0 :                 std::cout << " ERROR in executeQuery : " << rete << std::endl;
     452             :                 return rete;
     453             :             }
     454             :         }
     455             :         else
     456             :         {
     457             :             //puts("on a recu un buffer vide");
     458           0 :             if (lp.retval_set_query == -3)
     459           0 :                 send(lp.cs, "first char of query not valid, use a char in dDsSqacrReiECmlkzgpPeof", 68, 0);
     460           0 :             else if (lp.retval_set_query == 2)
     461           0 :                 send(lp.cs, "type not loaded in servereof", 28, 0);
     462           0 :             else if (lp.retval_set_query == -5 || lp.retval_set_query == -2)
     463           0 :                 send(lp.cs, "error in receiving messageeof", 29, 0);
     464           0 :             else if (lp.retval_set_query == -1)
     465           0 :                 send(lp.cs, "empty messageeof", 20, 0);
     466             :             else
     467           0 :                 send(lp.cs, "error in messageeof", 19, 0);
     468             :         }
     469             : 
     470           5 :         cur_query.reset_query();
     471           5 :         close(lp.cs);
     472           5 :         if (lp.counter < 0)
     473             :             break;
     474             :         }
     475             : 
     476           1 :         int ret_val = 0;
     477             :     // VR 13-10-16 : c'est quoi ce type de indexCurrent, saveOnExitWithSomeTry attend un int* (a virer d'ailleurs !)
     478             :     //ret_val = saveOnExitWithSomeTry(lp.indexCurrent, lp.verbose, gp.dontCheckDuplicateIdObject_);
     479           1 :     close(gp.sock_);
     480             : 
     481           1 :     std::cout<<" Fin de fvs ! "<<std::endl;
     482             : 
     483             :     return ret_val;
     484             : }

Generated by: LCOV version 1.14