Changeset bcf71ac in tol


Ignore:
Timestamp:
May 28, 2010, 11:47:00 AM (16 years ago)
Author:
Víctor de Buen <vdebuen@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
af1369e
Parents:
d74c90b
Message:

Fixes #546

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@2199 be4846ae-f051-483a-831f-b64e7d08527f

Location:
tol
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • tol/bbasic/sys.cpp

    rd74c90b rbcf71ac  
    995995//--------------------------------------------------------------------
    996996//Opens a file and locks it
    997 //If cannot do it then sleeps and retries again until time is out
    998 FILE* FOpenAndLock(
     997static FILE* fOpenAndLock(
     998   const char *filename,
     999   const char *mode)
     1000//--------------------------------------------------------------------
     1001{
     1002  FILE* fil=NULL;
     1003  #ifdef _MSC_VER
     1004  fopen_s(&fil, filename, mode);
     1005  #else
     1006  fil = fopen(filename, mode);
     1007  #endif
     1008  return(fil);
     1009}
     1010
     1011//--------------------------------------------------------------------
     1012//Opens a file and locks it
     1013//If doesn't can do it then sleeps and retries again until time is out
     1014FILE* BSys::FOpenAndLock(
    9991015   const char *filename,
    10001016   const char *mode,
    … …  
    10041020{
    10051021  FILE* fil=NULL;
     1022  double sleep = 1.0;
     1023  double sleepCum = 0.0;
     1024  int tryNum = 0;
     1025  bool ok = false;
     1026  do
     1027  {
     1028    #ifdef _MSC_VER
     1029    ok = fopen_s(&fil, filename, mode)==0;
     1030    #else
     1031    fil = fopen(filename, mode);
     1032    ok = fil!=NULL;
     1033    #endif
     1034    if(!ok)
     1035    {
     1036      fil = NULL;
     1037      BSys::SleepMilliSeconds((unsigned int)sleep);
     1038      sleepCum += sleep;
     1039      sleep = floor(1.1*sleep)+(1+timeOutInMilliseconds/100);
     1040      tryNum++;
     1041      Warning(BText("[BSys::FOpenAndLock] Retraying to open locked file ")+filename+" for "+tryNum+"-th time\n");
     1042    }
     1043  } while(!fil && (sleepCum<timeOutInMilliseconds));
     1044  if(!fil && errorMessage && errorMessage[0])
     1045  {
     1046    Error(BText("Cannot open file ")+filename+" in mode "+mode+"\n"+
     1047          errorMessage);
     1048  }
    10061049  return(fil);
    10071050}
    10081051
    10091052//--------------------------------------------------------------------
    1010 //Unlocks a file and close it
    1011 i FUnlockAndClose(FILE* file)
    1012 //--------------------------------------------------------------------
    1013 {
    1014   FILE* fil=NULL;
    1015   return(fil);
    1016 }
     1053//Unlocks a file and closes it
     1054bool BSys::FUnlockAndClose(FILE* file, const char *filename)
     1055//--------------------------------------------------------------------
     1056{
     1057  if(fclose(file))
     1058  {
     1059    Error(BText("Cannot close file ")+filename);
     1060    return(false);
     1061  }
     1062  return(true);
     1063}
  • tol/bbasic/tol_bsys.h

    rd74c90b rbcf71ac  
    164164   const char *filename,
    165165   const char *mode,
    166    unsigned int timeOutInMilliseconds=0,
    167    char* errorMessage=NULL);
     166   unsigned int timeOutInMilliseconds,
     167   char* errorMessage);
    168168  //Unlocks a file and close it
    169   static void FUnlockAndClose(FILE* file);
     169  static bool FUnlockAndClose(FILE* file, const char *filename);
    170170};
    171171
  • tol/btol/bdb/filehandle.cpp

    rd74c90b rbcf71ac  
    6161
    6262/////////////////////////////////////////////////////////////////////////////
    63  FILE* BFileDesc::CheckFileHandle(int handle, bool verbose, const BText& msg,
    64                                   BFileHashByHandle::const_iterator& found)
    65 /////////////////////////////////////////////////////////////////////////////
    66 {
    67   FILE* file;
     63 BFileDesc* BFileDesc::FindFileHandle(
     64  int handle, bool verbose, const BText& msg,
     65  BFileHashByHandle::const_iterator& found)
     66/////////////////////////////////////////////////////////////////////////////
     67{
     68  BFileDesc* fd;
    6869  found = FileHandle().find(handle);
    6970  if(found==FileHandle().end())
    7071  {
    71     file = NULL;
     72    fd = NULL;
    7273  }
    7374  else
    7475  {
    75     file = found->second->file_;
    76   }
    77   if(!file && verbose)
     76    fd = found->second;
     77  }
     78  if(!fd && verbose)
    7879  {
    7980    Error(I2("Invalid file descriptor ",
    8081             "Descriptor de fichero inválido ")+handle+"\n"+msg);
    8182  }
    82   return(file);
     83  return(fd);
     84};
     85
     86/////////////////////////////////////////////////////////////////////////////
     87 BFileDesc* BFileDesc::FindFileHandle(
     88   int handle, bool verbose, const BText& msg)
     89/////////////////////////////////////////////////////////////////////////////
     90{
     91  BFileHashByHandle::const_iterator found;
     92  return(FindFileHandle(handle, verbose, msg, found));
     93};
     94
     95/////////////////////////////////////////////////////////////////////////////
     96 FILE* BFileDesc::CheckFileHandle(int handle, bool verbose, const BText& msg,
     97                                  BFileHashByHandle::const_iterator& found)
     98/////////////////////////////////////////////////////////////////////////////
     99{
     100  BFileDesc* fd = FindFileHandle(handle, verbose, msg, found);
     101  return((fd)?fd->file_:NULL);
    83102};
    84103
  • tol/btol/bdb/tol_filehandle.h

    rd74c90b rbcf71ac  
    4444
    4545  static BFileHashByHandle& FileHandle();
     46  static BFileDesc* FindFileHandle(int handle, bool verbose, const BText& msg,
     47                             BFileHashByHandle::const_iterator& found);
     48
     49  static BFileDesc* FindFileHandle(int handle, bool verbose, const BText& msg);
    4650  static FILE* CheckFileHandle(int handle, bool verbose, const BText& msg,
    4751                             BFileHashByHandle::const_iterator& found);
  • tol/btol/matrix_type/matgra.cpp

    rd74c90b rbcf71ac  
    175175#endif
    176176
     177//Time out for open BBM files in milliseconds
     178#define BBM_TimeOut 1000
     179
    177180//--------------------------------------------------------------------
    178181void BBM_BinWrite(const BText& fileName, const BMat& M)
    179182//--------------------------------------------------------------------
    180183{
    181   FILE* fil = fopen(fileName.String(),"wb");
    182   if(!fil)
    183   {
    184     Error(I2("Cannot open for write BBM file ",
    185              "No se pudo abrir para escritura el fichero BBM ")+
    186           fileName);
    187     return;
    188   }
     184  FILE* fil = BSys::FOpenAndLock(fileName.String(),"wb",
     185   BBM_TimeOut, "Unexpected error writing to BBM file");
     186  if(!fil) { return; }
    189187  BInt m = M.Rows();
    190188  BInt n = M.Columns();
    … …  
    192190  fwrite(&n,sizeof(BInt),1,fil);
    193191  fwrite(M.Data().Buffer(), sizeof(BDat), n*m, fil);
    194 #ifndef NDEBUG
    195   int lastPos = ftell(fil);
    196 #endif
    197   if(fclose(fil))
    198   {
    199     Error(I2("Cannot close after writing BBM file ",
    200              "No se pudo cerrar despues de escribir el fichero BBM ")+
    201           fileName);
    202   };
    203 #ifndef NDEBUG
    204   BInt fs = GetFileSize(fileName);
    205   assert(fs==lastPos);
    206 #endif
     192  if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
    207193  BBM_CheckSize("BBM_BinWrite",fileName,m,n);
    208194}
    … …  
    229215 
    230216  /* open for overwrite */
    231   if(!(fil = fopen(fileName.String(), "r+b"))) {
    232     Error(I2("Cannot open (rewrite mode) BBM file ",
    233        "No se pudo abrir (modo de sobreescritura) el fichero BBM ") +
    234     fileName);
    235     return;
    236   }
    237   fpos_t pos = 0;
    238   fsetpos(fil, &pos);
     217  fil = BSys::FOpenAndLock(fileName.String(),"a+b",
     218   BBM_TimeOut, "Unexpected error appending BBM file");
     219  if(!fil) { return; }
     220  fpos_t pos;
     221  pos = 0; fsetpos(fil, &pos);
    239222  fread(&rows,sizeof(BInt),1,fil);
    240223  fread(&cols,sizeof(BInt),1,fil);
    241224  rows2w = M.Rows();
    242225  cols2w = M.Columns();
    243   if(cols!=cols2w) {
     226  if(cols!=cols2w)
     227  {
    244228    Error("MatAppendFile: Different number of columns");
    245     fclose(fil);
    246     return;
    247   }
    248   pos = 0;
    249   fsetpos(fil, &pos);
    250   rows += rows2w;
    251   fwrite(&rows, sizeof(BInt), 1, fil);
    252   fflush(fil);
    253   fclose(fil);
    254   fil = NULL;
    255   for(int tryNum = 0; !fil && (tryNum < 1000); tryNum++)
    256   {
    257     fil = fopen(fileName.String(), "ab");
    258   }
    259   /* open for append */
    260   if(!fil) {
    261     Error(I2("Cannot open (append mode) BBM file ",
    262        "No se pudo abrir (modo de insercion) el fichero BBM ") +
    263     fileName);
    264     return;
    265   }
    266   fwrite(M.Data().Buffer(), sizeof(BDat), rows2w*cols2w, fil);
    267   fflush(fil);
    268   if(fclose(fil))
    269   {
    270     Error(I2("Cannot close after append BBM file ",
    271              "No se pudo cerrar despues de añadir al fichero BBM ")+
    272           fileName);
    273   };
     229  }
     230  else
     231  {
     232    rows += rows2w;
     233    pos = rows*cols*sizeof(BDat)+2*sizeof(int); fsetpos(fil, &pos);
     234    fwrite(M.Data().Buffer(), sizeof(BDat), rows2w*cols2w, fil);
     235    if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
     236    fil = BSys::FOpenAndLock(fileName.String(),"r+b",
     237     BBM_TimeOut*10, "Unexpected error changing BBM file");
     238    if(!fil) { return; }
     239    pos = 0; fsetpos(fil, &pos);
     240    fwrite(&rows, sizeof(BInt), 1, fil);
     241  }
     242  BSys::FUnlockAndClose(fil,fileName.String());
    274243//BBM_CheckSize("BBM_BinAppend",fileName,rows,cols);
    275244}
    … …  
    282251  BInt fs = GetFileSize(fileName);
    283252//Std(BText("\nBBM_BinRead ")+fileName+" bytes "+fs);
    284   FILE* fil = fopen(fileName.String(),"rb");
    285   if(!fil)
    286   {
    287     Error(I2("Cannot open for read BBM file ",
    288              "No se pudo abrir para lectura el fichero BBM ")+
    289           fileName);
    290     return;
    291   }
     253  FILE* fil = BSys::FOpenAndLock(fileName.String(),"rb",
     254   BBM_TimeOut, "Unexpected error reading from BBM file");
     255  if(!fil) { return; }
     256
    292257  BInt i, m, n, mn;
    293258  fread(&m,sizeof(BInt),1,fil);
    … …  
    295260  if(!m || !n)
    296261  {
    297     fclose(fil);
     262    BSys::FUnlockAndClose(fil,fileName.String());
    298263    return;
    299264  }
    … …  
    306271    if(M.Rows()!=m) { return; }
    307272    fread(M.GetData().GetBuffer(), sizeof(BDat), mn, fil);
    308     if(fclose(fil))
    309     {
    310       Error(I2("Cannot close after reading BBM file ",
    311                "No se pudo cerrar despues de leer el fichero BBM ")+
    312             fileName);
    313     };
     273    if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
    314274  }
    315275  //In TOL versions before 2007-01-15 structure page size = 8 => sizeof(BDat)=16
    … …  
    320280    BArray<BOis::BDatOld> M_;
    321281    fread(M_.GetBuffer(), sizeof(BOis::BDatOld), mn, fil);
    322     if(fclose(fil))
    323     {
    324       Error(I2("Cannot close after reading BBM file ",
    325                "No se pudo cerrar despues de leer el fichero BBM ")+
    326             fileName);
    327     };
     282    if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
    328283    for(i=0; i<mn; i++)
    329284    {
    … …  
    343298    BDat* data   = M.GetData().GetBuffer();
    344299    fread(buffer, 1, s, fil);
    345     if(fclose(fil))
    346     {
    347       Error(I2("Cannot close after reading BBM file ",
    348                "No se pudo cerrar despues de leer el fichero BBM ")+
    349             fileName);
    350     };
     300    if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
    351301    for(i=0; i<mn; i++)
    352302    {
    … …  
    371321    M.Alloc(m,n);
    372322    fread(M.GetData().GetBuffer(), sizeof(BDat), mn, fil);
    373     if(fclose(fil))
    374     {
    375       Error(I2("Cannot close after reading BBM file ",
    376                "No se pudo cerrar despues de leer el fichero BBM ")+
    377             fileName);
    378     };
    379 
     323    if(!BSys::FUnlockAndClose(fil,fileName.String())) { return; }
    380324  }
    381325  else
    … …  
    386330
    387331//--------------------------------------------------------------------
    388 void BBM_BinReadRows(FILE* fil, BMat& M,
     332void BBM_BinReadRows(FILE* fil,
     333                     const BText& fileName,
     334                     BMat& M,
    389335                     int m, int n,
    390336                     int i, int r, int t=1)
    … …  
    441387
    442388//--------------------------------------------------------------------
    443 void BBM_BinReadCell(FILE* fil, BDat& cell,
     389void BBM_BinReadCell(FILE* fil,
     390                     const BText& fileName,
     391                     BDat& cell,
    444392                     int m, int n,
    445393                     int i, int j)
    … …  
    455403     (0>j)||(j>=n) )
    456404  {
    457     fclose(fil);
     405    BSys::FUnlockAndClose(fil,fileName.String());
    458406    return;
    459407  }
    … …  
    470418  BInt fs = GetFileSize(fileName);
    471419//Std(BText("\nBBM_BinRead ")+fileName+" bytes "+fs);
    472   FILE* fil = fopen(fileName.String(),"rb");
    473   if(!fil)
    474   {
    475     Error(I2("Cannot open for read BBM file ",
    476              "No se pudo abrir para lectura el fichero BBM ")+
    477           fileName);
    478     return;
    479   }
     420  FILE* fil = BSys::FOpenAndLock(fileName.String(),"rb",
     421   BBM_TimeOut, "Unexpected error reading from BBM file");
     422  if(!fil) { return; }
    480423  fread(&rows,   sizeof(BInt),1,fil);
    481424  fread(&columns,sizeof(BInt),1,fil);
    482   if(fclose(fil))
    483   {
    484     Error(I2("Cannot close after reading BBM file ",
    485              "No se pudo cerrar despues de leer el fichero BBM ")+
    486           fileName);
    487   };
     425  BSys::FUnlockAndClose(fil,fileName.String());
    488426}
    489427
    … …  
    649587  {
    650588    int handle = (int)Real(Arg(1));
    651     FILE* file = BFileDesc::CheckFileHandle(handle,true,
     589    BFileDesc* fd = BFileDesc::FindFileHandle(handle,true,
    652590      I2("Fail in ","Fallo en ")+"BMatReadRows"); 
    653     if(file)
    654     {
    655       BBM_BinReadRows(file,contens_,m,n,i,r,t);
     591    if(fd)
     592    {
     593      BBM_BinReadRows(fd->file_,fd->path_.String(),contens_,m,n,i,r,t);
    656594    }
    657595  }
    … …  
    659597  {
    660598    BText& path = Text(Arg(1));
    661     file = fopen(path.String(),"rb");
    662     if(!file)
    663     {
    664       Error(I2("Cannot open for MatReadRows BBM file ",
    665                "No se pudo abrir para MatReadRows el fichero BBM ")+
    666             path);
    667       return;
    668     }
    669     BBM_BinReadRows(file,contens_,m,n,i,r,t);
    670     fclose(file);
     599    file = BSys::FOpenAndLock(path.String(),"rb",
     600      BBM_TimeOut, "Unexpected error reading from BBM file");
     601    if(!file) { return; }
     602    BBM_BinReadRows(file,path.String(),contens_,m,n,i,r,t);
     603    BSys::FUnlockAndClose(file,path.String());
    671604  }
    672605}
    … …  
    711644  {
    712645    int handle = (int)Real(Arg(1));
    713     FILE* file = BFileDesc::CheckFileHandle(handle,true,
     646    BFileDesc* fd = BFileDesc::FindFileHandle(handle,true,
    714647      I2("Fail in ","Fallo en ")+"MatReadCell"); 
    715     if(file)
    716     {
    717       BBM_BinReadCell(file,contens_,m,n,i,j);
     648    if(fd)
     649    {
     650      BBM_BinReadCell(fd->file_,fd->path_.String(),contens_,m,n,i,j);
    718651    }
    719652  }
    … …  
    721654  {
    722655    BText& path = Text(Arg(1));
    723     file = fopen(path.String(),"rb");
    724     if(!file)
    725     {
    726       Error(I2("Cannot open for MatReadCell BBM file ",
    727                "No se pudo abrir para MatReadCell el fichero BBM ")+
    728             path);
    729       return;
    730     }
    731     BBM_BinReadCell(file,contens_,m,n,i,j);
    732     fclose(file);
     656    file = BSys::FOpenAndLock(path.String(),"rb",
     657     BBM_TimeOut, "Unexpected error reading from BBM file");
     658    if(!file) { return; }
     659    BBM_BinReadCell(file,path.String(),contens_,m,n,i,j);
     660    BSys::FUnlockAndClose(file,path.String());
    733661  }
    734662}
Note: See TracChangeset for help on using the changeset viewer.