/ Check-in [680cc064]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Implement xUnlink, xShmMap, and xShmUnmap for lsm1 on Win32.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | lsm-vtab
Files: files | file ages | folders
SHA3-256: 680cc064c9e809ddc643074b5e65677f484d904b3d52826f6def480ddaa8f0ab
User & Date: mistachkin 2017-06-29 12:54:58
Context
2017-06-29
13:19
Add the LSM1 extension. check-in: 824e8327 user: drh tags: trunk
12:54
Implement xUnlink, xShmMap, and xShmUnmap for lsm1 on Win32. Closed-Leaf check-in: 680cc064 user: mistachkin tags: lsm-vtab
00:20
Implement xRemap for lsm1 on Win32. Also, zero file handle when closing it. check-in: 93c9aa7d user: mistachkin tags: lsm-vtab
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/lsm1/lsm_win32.c.

    37     37   
    38     38     HANDLE hFile;                   /* Open file handle */
    39     39     HANDLE hShmFile;                /* File handle for *-shm file */
    40     40   
    41     41     HANDLE hMap;                    /* File handle for mapping */
    42     42     LPVOID pMap;                    /* Pointer to mapping of file fd */
    43     43     size_t nMap;                    /* Size of mapping at pMap in bytes */
    44         -  int nShm;                       /* Number of entries in array apShm[] */
    45         -  void **apShm;                   /* Array of 32K shared memory segments */
           44  +  int nShm;                       /* Number of entries in ahShm[]/apShm[] */
           45  +  LPHANDLE ahShm;                 /* Array of handles for shared mappings */
           46  +  LPVOID *apShm;                  /* Array of 32K shared memory segments */
    46     47   };
    47     48   
    48     49   static char *win32ShmFile(Win32File *p){
    49     50     char *zShm;
    50     51     int nName = strlen(p->zName);
    51     52     zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1);
    52     53     if( zShm ){
................................................................................
   182    183     return zText;
   183    184   }
   184    185   
   185    186   #if !defined(win32IsNotFound)
   186    187   #define win32IsNotFound(a) (((a)==ERROR_FILE_NOT_FOUND)  || \
   187    188                               ((a)==ERROR_PATH_NOT_FOUND))
   188    189   #endif
          190  +
          191  +static int win32Open(
          192  +  lsm_env *pEnv,
          193  +  const char *zFile,
          194  +  int flags,
          195  +  LPHANDLE phFile
          196  +){
          197  +  int rc;
          198  +  LPWSTR zConverted;
          199  +
          200  +  zConverted = win32Utf8ToUnicode(pEnv, zFile);
          201  +  if( zConverted==0 ){
          202  +    rc = LSM_NOMEM_BKPT;
          203  +  }else{
          204  +    int bReadonly = (flags & LSM_OPEN_READONLY);
          205  +    DWORD dwDesiredAccess;
          206  +    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
          207  +    DWORD dwCreationDisposition;
          208  +    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
          209  +    HANDLE hFile;
          210  +    int nRetry = 0;
          211  +    if( bReadonly ){
          212  +      dwDesiredAccess = GENERIC_READ;
          213  +      dwCreationDisposition = OPEN_EXISTING;
          214  +    }else{
          215  +      dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
          216  +      dwCreationDisposition = OPEN_ALWAYS;
          217  +    }
          218  +    while( (hFile = CreateFileW((LPCWSTR)zConverted,
          219  +                                dwDesiredAccess,
          220  +                                dwShareMode, NULL,
          221  +                                dwCreationDisposition,
          222  +                                dwFlagsAndAttributes,
          223  +                                NULL))==INVALID_HANDLE_VALUE &&
          224  +                                win32RetryIoerr(pEnv, &nRetry) ){
          225  +      /* Noop */
          226  +    }
          227  +    lsmFree(pEnv, zConverted);
          228  +    if( hFile!=INVALID_HANDLE_VALUE ){
          229  +      *phFile = hFile;
          230  +      rc = LSM_OK;
          231  +    }else{
          232  +      if( win32IsNotFound(GetLastError()) ){
          233  +        rc = lsmErrorBkpt(LSM_IOERR_NOENT);
          234  +      }else{
          235  +        rc = LSM_IOERR_BKPT;
          236  +      }
          237  +    }
          238  +  }
          239  +  return rc;
          240  +}
   189    241   
   190    242   static int lsmWin32OsOpen(
   191    243     lsm_env *pEnv,
   192    244     const char *zFile,
   193    245     int flags,
   194    246     lsm_file **ppFile
   195    247   ){
................................................................................
   196    248     int rc = LSM_OK;
   197    249     Win32File *pWin32File;
   198    250   
   199    251     pWin32File = lsmMallocZero(pEnv, sizeof(Win32File));
   200    252     if( pWin32File==0 ){
   201    253       rc = LSM_NOMEM_BKPT;
   202    254     }else{
   203         -    LPWSTR zConverted;
   204         -    int bReadonly = (flags & LSM_OPEN_READONLY);
   205         -    DWORD dwDesiredAccess;
   206         -    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
   207         -    DWORD dwCreationDisposition;
   208         -    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
   209    255       HANDLE hFile;
   210    256   
   211         -    zConverted = win32Utf8ToUnicode(pEnv, zFile);
   212         -    if( zConverted==0 ){
          257  +    rc = win32Open(pEnv, zFile, flags, &hFile);
          258  +    if( rc==LSM_OK ){
          259  +      pWin32File->pEnv = pEnv;
          260  +      pWin32File->zName = zFile;
          261  +      pWin32File->hFile = hFile;
          262  +    }else{
   213    263         lsmFree(pEnv, pWin32File);
   214    264         pWin32File = 0;
   215         -      rc = LSM_NOMEM_BKPT;
   216         -    }else{
   217         -      int nRetry = 0;
   218         -      if( bReadonly ){
   219         -        dwDesiredAccess = GENERIC_READ;
   220         -        dwCreationDisposition = OPEN_EXISTING;
   221         -      }else{
   222         -        dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
   223         -        dwCreationDisposition = OPEN_ALWAYS;
   224         -      }
   225         -      while( (hFile = CreateFileW((LPCWSTR)zConverted,
   226         -                                  dwDesiredAccess,
   227         -                                  dwShareMode, NULL,
   228         -                                  dwCreationDisposition,
   229         -                                  dwFlagsAndAttributes,
   230         -                                  NULL))==INVALID_HANDLE_VALUE &&
   231         -                                  win32RetryIoerr(pEnv, &nRetry) ){
   232         -        /* Noop */
   233         -      }
   234         -      lsmFree(pEnv, zConverted);
   235         -      if( hFile!=INVALID_HANDLE_VALUE ){
   236         -        pWin32File->pEnv = pEnv;
   237         -        pWin32File->zName = zFile;
   238         -        pWin32File->hFile = hFile;
   239         -      }else{
   240         -        lsmFree(pEnv, pWin32File);
   241         -        pWin32File = 0;
   242         -        if( win32IsNotFound(GetLastError()) ){
   243         -          rc = lsmErrorBkpt(LSM_IOERR_NOENT);
   244         -        }else{
   245         -          rc = LSM_IOERR_BKPT;
   246         -        }
   247         -      }
   248    265       }
   249    266     }
   250    267     *ppFile = (lsm_file *)pWin32File;
   251    268     return rc;
   252    269   }
   253    270   
   254    271   static int lsmWin32OsWrite(
................................................................................
   281    298       overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
   282    299       aRem += nWrite;
   283    300       nRem -= nWrite;
   284    301     }
   285    302     if( nRem!=0 ) return LSM_IOERR_BKPT;
   286    303     return LSM_OK;
   287    304   }
          305  +
          306  +static int win32Truncate(
          307  +  HANDLE hFile,
          308  +  lsm_i64 nSize
          309  +){
          310  +  LARGE_INTEGER offset;
          311  +  offset.QuadPart = nSize;
          312  +  if( !SetFilePointerEx(hFile, offset, 0, FILE_BEGIN) ){
          313  +    return LSM_IOERR_BKPT;
          314  +  }
          315  +  if (!SetEndOfFile(hFile) ){
          316  +    return LSM_IOERR_BKPT;
          317  +  }
          318  +  return LSM_OK;
          319  +}
   288    320   
   289    321   static int lsmWin32OsTruncate(
   290    322     lsm_file *pFile, /* File to write to */
   291    323     lsm_i64 nSize    /* Size to truncate file to */
   292    324   ){
   293    325     Win32File *pWin32File = (Win32File *)pFile;
   294         -  LARGE_INTEGER offset;
   295         -
   296         -  offset.QuadPart = nSize;
   297         -  if( !SetFilePointerEx(pWin32File->hFile, offset, 0, FILE_BEGIN) ){
   298         -    return LSM_IOERR_BKPT;
   299         -  }
   300         -  if (!SetEndOfFile(pWin32File->hFile) ){
   301         -    return LSM_IOERR_BKPT;
   302         -  }
   303         -  return LSM_OK;
          326  +  return win32Truncate(pWin32File->hFile, nSize);
   304    327   }
   305    328   
   306    329   static int lsmWin32OsRead(
   307    330     lsm_file *pFile, /* File to read from */
   308    331     lsm_i64 iOff,    /* Offset to read from */
   309    332     void *pData,     /* Read data into this buffer */
   310    333     int nData        /* Bytes of data to read */
................................................................................
   503    526     nReq = sizeof(fileInfo.nFileIndexHigh);
   504    527     memcpy(pBuf, &fileInfo.nFileIndexHigh, nReq);
   505    528     pBuf2 += nReq;
   506    529     nReq = sizeof(fileInfo.nFileIndexLow);
   507    530     memcpy(pBuf2, &fileInfo.nFileIndexLow, nReq);
   508    531     return LSM_OK;
   509    532   }
          533  +
          534  +static int win32Delete(
          535  +  lsm_env *pEnv,
          536  +  const char *zFile
          537  +){
          538  +  int rc;
          539  +  LPWSTR zConverted;
          540  +
          541  +  zConverted = win32Utf8ToUnicode(pEnv, zFile);
          542  +  if( zConverted==0 ){
          543  +    rc = LSM_NOMEM_BKPT;
          544  +  }else{
          545  +    int nRetry = 0;
          546  +    DWORD attr;
          547  +    DWORD lastErrno;
          548  +
          549  +    do {
          550  +      attr = GetFileAttributesW(zConverted);
          551  +      if ( attr==INVALID_FILE_ATTRIBUTES ){
          552  +        rc = LSM_IOERR_BKPT;
          553  +        break;
          554  +      }
          555  +      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
          556  +        rc = LSM_IOERR_BKPT; /* Files only. */
          557  +        break;
          558  +      }
          559  +      if ( DeleteFileW(zConverted) ){
          560  +        rc = LSM_OK; /* Deleted OK. */
          561  +        break;
          562  +      }
          563  +      if ( !win32RetryIoerr(pEnv, &nRetry) ){
          564  +        rc = LSM_IOERR_BKPT; /* No more retries. */
          565  +        break;
          566  +      }
          567  +    }while( 1 );
          568  +  }
          569  +  lsmFree(pEnv, zConverted);
          570  +  return rc;
          571  +}
   510    572   
   511    573   static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){
   512         -  return LSM_ERROR;
          574  +  return win32Delete(pEnv, zFile);
   513    575   }
   514    576   
   515    577   int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
   516    578     Win32File *pWin32File = (Win32File *)pFile;
   517    579     OVERLAPPED ovlp;
   518    580   
   519    581     assert( LSM_LOCK_UNLOCK==0 );
................................................................................
   565    627       }
   566    628     }
   567    629     UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp);
   568    630     return LSM_OK;
   569    631   }
   570    632   
   571    633   int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
   572         -  return LSM_ERROR;
          634  +  int rc;
          635  +  Win32File *pWin32File = (Win32File *)pFile;
          636  +
          637  +  *ppShm = NULL;
          638  +  assert( sz>=0 );
          639  +  assert( sz==LSM_SHM_CHUNK_SIZE );
          640  +  if( iChunk>=pWin32File->nShm ){
          641  +    int i;
          642  +    void **apNew;
          643  +    int nNew = iChunk+1;
          644  +    lsm_i64 nReq = nNew * sz;
          645  +    LARGE_INTEGER fileSize;
          646  +
          647  +    /* If the shared-memory file has not been opened, open it now. */
          648  +    if( pWin32File->hShmFile==NULL ){
          649  +      char *zShm = win32ShmFile(pWin32File);
          650  +      if( !zShm ) return LSM_NOMEM_BKPT;
          651  +      rc = win32Open(pWin32File->pEnv, zShm, 0, &pWin32File->hShmFile);
          652  +      lsmFree(pWin32File->pEnv, zShm);
          653  +      if( rc!=LSM_OK ){
          654  +        return rc;
          655  +      }
          656  +    }
          657  +
          658  +    /* If the shared-memory file is not large enough to contain the
          659  +    ** requested chunk, cause it to grow.  */
          660  +    memset(&fileSize, 0, sizeof(LARGE_INTEGER));
          661  +    if( !GetFileSizeEx(pWin32File->hShmFile, &fileSize) ){
          662  +      return LSM_IOERR_BKPT;
          663  +    }
          664  +    assert( fileSize.QuadPart>=0 );
          665  +    if( fileSize.QuadPart<nReq ){
          666  +      rc = win32Truncate(pWin32File->hShmFile, nReq);
          667  +      if( rc!=LSM_OK ){
          668  +        return rc;
          669  +      }
          670  +    }
          671  +
          672  +    apNew = (void **)lsmRealloc(pWin32File->pEnv, pWin32File->apShm,
          673  +                                sizeof(LPVOID) * nNew);
          674  +    if( !apNew ) return LSM_NOMEM_BKPT;
          675  +    for(i=pWin32File->nShm; i<nNew; i++){
          676  +      apNew[i] = NULL;
          677  +    }
          678  +    pWin32File->apShm = apNew;
          679  +    pWin32File->nShm = nNew;
          680  +  }
          681  +
          682  +  if( pWin32File->apShm[iChunk]==NULL ){
          683  +    HANDLE hMap;
          684  +    LPVOID pMap;
          685  +    hMap = CreateFileMappingW(pWin32File->hShmFile, NULL, PAGE_READWRITE, 0,
          686  +                              (DWORD)sz, NULL);
          687  +    if( hMap==NULL ){
          688  +      return LSM_IOERR_BKPT;
          689  +    }
          690  +    pWin32File->ahShm[iChunk] = hMap;
          691  +    pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0,
          692  +                         (SIZE_T)sz);
          693  +    if( pMap==NULL ){
          694  +      return LSM_IOERR_BKPT;
          695  +    }
          696  +    pWin32File->apShm[iChunk] = pMap;
          697  +    pWin32File->nMap = (SIZE_T)sz;
          698  +  }
          699  +  *ppShm = pWin32File->apShm[iChunk];
          700  +  return LSM_OK;
   573    701   }
   574    702   
   575    703   void lsmWin32OsShmBarrier(void){
   576    704     MemoryBarrier();
   577    705   }
   578    706   
   579    707   int lsmWin32OsShmUnmap(lsm_file *pFile, int bDelete){
   580         -  return LSM_ERROR;
          708  +  Win32File *pWin32File = (Win32File *)pFile;
          709  +
          710  +  if( pWin32File->hShmFile!=NULL ){
          711  +    int i;
          712  +    for(i=0; i<pWin32File->nShm; i++){
          713  +      if( pWin32File->apShm[i]!=NULL ){
          714  +        UnmapViewOfFile(pWin32File->apShm[i]);
          715  +        pWin32File->apShm[i] = NULL;
          716  +      }
          717  +      if( pWin32File->ahShm[i]!=NULL ){
          718  +        CloseHandle(pWin32File->ahShm[i]);
          719  +        pWin32File->ahShm[i] = NULL;
          720  +      }
          721  +    }
          722  +    CloseHandle(pWin32File->hShmFile);
          723  +    pWin32File->hShmFile = 0;
          724  +    if( bDelete ){
          725  +      char *zShm = win32ShmFile(pWin32File);
          726  +      if( zShm ){ win32Delete(pWin32File->pEnv, zShm); }
          727  +      lsmFree(pWin32File->pEnv, zShm);
          728  +    }
          729  +  }
          730  +  return LSM_OK;
   581    731   }
   582    732   
   583    733   #define MX_CLOSE_ATTEMPT 3
   584    734   static int lsmWin32OsClose(lsm_file *pFile){
   585    735     int rc;
   586    736     int nRetry = 0;
   587    737     Win32File *pWin32File = (Win32File *)pFile;