SQLite

Check-in [680cc064c9]
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
Timelines: family | ancestors | descendants | both | lsm-vtab
Files: files | file ages | folders
SHA3-256: 680cc064c9e809ddc643074b5e65677f484d904b3d52826f6def480ddaa8f0ab
User & Date: mistachkin 2017-06-29 12:54:58.254
Context
2017-06-29
13:19
Add the LSM1 extension. (check-in: 824e83274c user: drh tags: trunk)
12:54
Implement xUnlink, xShmMap, and xShmUnmap for lsm1 on Win32. (Closed-Leaf check-in: 680cc064c9 user: mistachkin tags: lsm-vtab)
00:20
Implement xRemap for lsm1 on Win32. Also, zero file handle when closing it. (check-in: 93c9aa7d9a user: mistachkin tags: lsm-vtab)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/lsm1/lsm_win32.c.
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

  HANDLE hFile;                   /* Open file handle */
  HANDLE hShmFile;                /* File handle for *-shm file */

  HANDLE hMap;                    /* File handle for mapping */
  LPVOID pMap;                    /* Pointer to mapping of file fd */
  size_t nMap;                    /* Size of mapping at pMap in bytes */
  int nShm;                       /* Number of entries in array apShm[] */

  void **apShm;                   /* Array of 32K shared memory segments */
};

static char *win32ShmFile(Win32File *p){
  char *zShm;
  int nName = strlen(p->zName);
  zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1);
  if( zShm ){







|
>
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

  HANDLE hFile;                   /* Open file handle */
  HANDLE hShmFile;                /* File handle for *-shm file */

  HANDLE hMap;                    /* File handle for mapping */
  LPVOID pMap;                    /* Pointer to mapping of file fd */
  size_t nMap;                    /* Size of mapping at pMap in bytes */
  int nShm;                       /* Number of entries in ahShm[]/apShm[] */
  LPHANDLE ahShm;                 /* Array of handles for shared mappings */
  LPVOID *apShm;                  /* Array of 32K shared memory segments */
};

static char *win32ShmFile(Win32File *p){
  char *zShm;
  int nName = strlen(p->zName);
  zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1);
  if( zShm ){
182
183
184
185
186
187
188



















































189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  return zText;
}

#if !defined(win32IsNotFound)
#define win32IsNotFound(a) (((a)==ERROR_FILE_NOT_FOUND)  || \
                            ((a)==ERROR_PATH_NOT_FOUND))
#endif




















































static int lsmWin32OsOpen(
  lsm_env *pEnv,
  const char *zFile,
  int flags,
  lsm_file **ppFile
){
  int rc = LSM_OK;
  Win32File *pWin32File;

  pWin32File = lsmMallocZero(pEnv, sizeof(Win32File));
  if( pWin32File==0 ){
    rc = LSM_NOMEM_BKPT;
  }else{
    LPWSTR zConverted;
    int bReadonly = (flags & LSM_OPEN_READONLY);
    DWORD dwDesiredAccess;
    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
    DWORD dwCreationDisposition;
    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
    HANDLE hFile;

    zConverted = win32Utf8ToUnicode(pEnv, zFile);
    if( zConverted==0 ){
      lsmFree(pEnv, pWin32File);
      pWin32File = 0;
      rc = LSM_NOMEM_BKPT;
    }else{
      int nRetry = 0;
      if( bReadonly ){
        dwDesiredAccess = GENERIC_READ;
        dwCreationDisposition = OPEN_EXISTING;
      }else{
        dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
        dwCreationDisposition = OPEN_ALWAYS;
      }
      while( (hFile = CreateFileW((LPCWSTR)zConverted,
                                  dwDesiredAccess,
                                  dwShareMode, NULL,
                                  dwCreationDisposition,
                                  dwFlagsAndAttributes,
                                  NULL))==INVALID_HANDLE_VALUE &&
                                  win32RetryIoerr(pEnv, &nRetry) ){
        /* Noop */
      }
      lsmFree(pEnv, zConverted);
      if( hFile!=INVALID_HANDLE_VALUE ){
        pWin32File->pEnv = pEnv;
        pWin32File->zName = zFile;
        pWin32File->hFile = hFile;
      }else{
        lsmFree(pEnv, pWin32File);
        pWin32File = 0;
        if( win32IsNotFound(GetLastError()) ){
          rc = lsmErrorBkpt(LSM_IOERR_NOENT);
        }else{
          rc = LSM_IOERR_BKPT;
        }
      }
    }
  }
  *ppFile = (lsm_file *)pWin32File;
  return rc;
}

static int lsmWin32OsWrite(







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














<
<
<
<
<
<


|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
<
<
<
<
<







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254






255
256
257






258

















259
260
261
262
263
264






265
266
267
268
269
270
271
  return zText;
}

#if !defined(win32IsNotFound)
#define win32IsNotFound(a) (((a)==ERROR_FILE_NOT_FOUND)  || \
                            ((a)==ERROR_PATH_NOT_FOUND))
#endif

static int win32Open(
  lsm_env *pEnv,
  const char *zFile,
  int flags,
  LPHANDLE phFile
){
  int rc;
  LPWSTR zConverted;

  zConverted = win32Utf8ToUnicode(pEnv, zFile);
  if( zConverted==0 ){
    rc = LSM_NOMEM_BKPT;
  }else{
    int bReadonly = (flags & LSM_OPEN_READONLY);
    DWORD dwDesiredAccess;
    DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
    DWORD dwCreationDisposition;
    DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
    HANDLE hFile;
    int nRetry = 0;
    if( bReadonly ){
      dwDesiredAccess = GENERIC_READ;
      dwCreationDisposition = OPEN_EXISTING;
    }else{
      dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
      dwCreationDisposition = OPEN_ALWAYS;
    }
    while( (hFile = CreateFileW((LPCWSTR)zConverted,
                                dwDesiredAccess,
                                dwShareMode, NULL,
                                dwCreationDisposition,
                                dwFlagsAndAttributes,
                                NULL))==INVALID_HANDLE_VALUE &&
                                win32RetryIoerr(pEnv, &nRetry) ){
      /* Noop */
    }
    lsmFree(pEnv, zConverted);
    if( hFile!=INVALID_HANDLE_VALUE ){
      *phFile = hFile;
      rc = LSM_OK;
    }else{
      if( win32IsNotFound(GetLastError()) ){
        rc = lsmErrorBkpt(LSM_IOERR_NOENT);
      }else{
        rc = LSM_IOERR_BKPT;
      }
    }
  }
  return rc;
}

static int lsmWin32OsOpen(
  lsm_env *pEnv,
  const char *zFile,
  int flags,
  lsm_file **ppFile
){
  int rc = LSM_OK;
  Win32File *pWin32File;

  pWin32File = lsmMallocZero(pEnv, sizeof(Win32File));
  if( pWin32File==0 ){
    rc = LSM_NOMEM_BKPT;
  }else{






    HANDLE hFile;

    rc = win32Open(pEnv, zFile, flags, &hFile);






    if( rc==LSM_OK ){

















      pWin32File->pEnv = pEnv;
      pWin32File->zName = zFile;
      pWin32File->hFile = hFile;
    }else{
      lsmFree(pEnv, pWin32File);
      pWin32File = 0;






    }
  }
  *ppFile = (lsm_file *)pWin32File;
  return rc;
}

static int lsmWin32OsWrite(
281
282
283
284
285
286
287















288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
    aRem += nWrite;
    nRem -= nWrite;
  }
  if( nRem!=0 ) return LSM_IOERR_BKPT;
  return LSM_OK;
}
















static int lsmWin32OsTruncate(
  lsm_file *pFile, /* File to write to */
  lsm_i64 nSize    /* Size to truncate file to */
){
  Win32File *pWin32File = (Win32File *)pFile;
  LARGE_INTEGER offset;

  offset.QuadPart = nSize;
  if( !SetFilePointerEx(pWin32File->hFile, offset, 0, FILE_BEGIN) ){
    return LSM_IOERR_BKPT;
  }
  if (!SetEndOfFile(pWin32File->hFile) ){
    return LSM_IOERR_BKPT;
  }
  return LSM_OK;
}

static int lsmWin32OsRead(
  lsm_file *pFile, /* File to read from */
  lsm_i64 iOff,    /* Offset to read from */
  void *pData,     /* Read data into this buffer */
  int nData        /* Bytes of data to read */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<
<
<
<
<
<
|
<
<
<







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325






326



327
328
329
330
331
332
333
    overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
    aRem += nWrite;
    nRem -= nWrite;
  }
  if( nRem!=0 ) return LSM_IOERR_BKPT;
  return LSM_OK;
}

static int win32Truncate(
  HANDLE hFile,
  lsm_i64 nSize
){
  LARGE_INTEGER offset;
  offset.QuadPart = nSize;
  if( !SetFilePointerEx(hFile, offset, 0, FILE_BEGIN) ){
    return LSM_IOERR_BKPT;
  }
  if (!SetEndOfFile(hFile) ){
    return LSM_IOERR_BKPT;
  }
  return LSM_OK;
}

static int lsmWin32OsTruncate(
  lsm_file *pFile, /* File to write to */
  lsm_i64 nSize    /* Size to truncate file to */
){
  Win32File *pWin32File = (Win32File *)pFile;






  return win32Truncate(pWin32File->hFile, nSize);



}

static int lsmWin32OsRead(
  lsm_file *pFile, /* File to read from */
  lsm_i64 iOff,    /* Offset to read from */
  void *pData,     /* Read data into this buffer */
  int nData        /* Bytes of data to read */
503
504
505
506
507
508
509
510







































511
512
513
514
515
516
517
518
519
  nReq = sizeof(fileInfo.nFileIndexHigh);
  memcpy(pBuf, &fileInfo.nFileIndexHigh, nReq);
  pBuf2 += nReq;
  nReq = sizeof(fileInfo.nFileIndexLow);
  memcpy(pBuf2, &fileInfo.nFileIndexLow, nReq);
  return LSM_OK;
}








































static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){
  return LSM_ERROR;
}

int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED ovlp;

  assert( LSM_LOCK_UNLOCK==0 );








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
  nReq = sizeof(fileInfo.nFileIndexHigh);
  memcpy(pBuf, &fileInfo.nFileIndexHigh, nReq);
  pBuf2 += nReq;
  nReq = sizeof(fileInfo.nFileIndexLow);
  memcpy(pBuf2, &fileInfo.nFileIndexLow, nReq);
  return LSM_OK;
}

static int win32Delete(
  lsm_env *pEnv,
  const char *zFile
){
  int rc;
  LPWSTR zConverted;

  zConverted = win32Utf8ToUnicode(pEnv, zFile);
  if( zConverted==0 ){
    rc = LSM_NOMEM_BKPT;
  }else{
    int nRetry = 0;
    DWORD attr;
    DWORD lastErrno;

    do {
      attr = GetFileAttributesW(zConverted);
      if ( attr==INVALID_FILE_ATTRIBUTES ){
        rc = LSM_IOERR_BKPT;
        break;
      }
      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
        rc = LSM_IOERR_BKPT; /* Files only. */
        break;
      }
      if ( DeleteFileW(zConverted) ){
        rc = LSM_OK; /* Deleted OK. */
        break;
      }
      if ( !win32RetryIoerr(pEnv, &nRetry) ){
        rc = LSM_IOERR_BKPT; /* No more retries. */
        break;
      }
    }while( 1 );
  }
  lsmFree(pEnv, zConverted);
  return rc;
}

static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){
  return win32Delete(pEnv, zFile);
}

int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED ovlp;

  assert( LSM_LOCK_UNLOCK==0 );
565
566
567
568
569
570
571


































































572
573
574
575
576
577
578
579






















580
581
582
583
584
585
586
587
    }
  }
  UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp);
  return LSM_OK;
}

int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){


































































  return LSM_ERROR;
}

void lsmWin32OsShmBarrier(void){
  MemoryBarrier();
}

int lsmWin32OsShmUnmap(lsm_file *pFile, int bDelete){






















  return LSM_ERROR;
}

#define MX_CLOSE_ATTEMPT 3
static int lsmWin32OsClose(lsm_file *pFile){
  int rc;
  int nRetry = 0;
  Win32File *pWin32File = (Win32File *)pFile;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    }
  }
  UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp);
  return LSM_OK;
}

int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
  int rc;
  Win32File *pWin32File = (Win32File *)pFile;

  *ppShm = NULL;
  assert( sz>=0 );
  assert( sz==LSM_SHM_CHUNK_SIZE );
  if( iChunk>=pWin32File->nShm ){
    int i;
    void **apNew;
    int nNew = iChunk+1;
    lsm_i64 nReq = nNew * sz;
    LARGE_INTEGER fileSize;

    /* If the shared-memory file has not been opened, open it now. */
    if( pWin32File->hShmFile==NULL ){
      char *zShm = win32ShmFile(pWin32File);
      if( !zShm ) return LSM_NOMEM_BKPT;
      rc = win32Open(pWin32File->pEnv, zShm, 0, &pWin32File->hShmFile);
      lsmFree(pWin32File->pEnv, zShm);
      if( rc!=LSM_OK ){
        return rc;
      }
    }

    /* If the shared-memory file is not large enough to contain the
    ** requested chunk, cause it to grow.  */
    memset(&fileSize, 0, sizeof(LARGE_INTEGER));
    if( !GetFileSizeEx(pWin32File->hShmFile, &fileSize) ){
      return LSM_IOERR_BKPT;
    }
    assert( fileSize.QuadPart>=0 );
    if( fileSize.QuadPart<nReq ){
      rc = win32Truncate(pWin32File->hShmFile, nReq);
      if( rc!=LSM_OK ){
        return rc;
      }
    }

    apNew = (void **)lsmRealloc(pWin32File->pEnv, pWin32File->apShm,
                                sizeof(LPVOID) * nNew);
    if( !apNew ) return LSM_NOMEM_BKPT;
    for(i=pWin32File->nShm; i<nNew; i++){
      apNew[i] = NULL;
    }
    pWin32File->apShm = apNew;
    pWin32File->nShm = nNew;
  }

  if( pWin32File->apShm[iChunk]==NULL ){
    HANDLE hMap;
    LPVOID pMap;
    hMap = CreateFileMappingW(pWin32File->hShmFile, NULL, PAGE_READWRITE, 0,
                              (DWORD)sz, NULL);
    if( hMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->ahShm[iChunk] = hMap;
    pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0,
                         (SIZE_T)sz);
    if( pMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->apShm[iChunk] = pMap;
    pWin32File->nMap = (SIZE_T)sz;
  }
  *ppShm = pWin32File->apShm[iChunk];
  return LSM_OK;
}

void lsmWin32OsShmBarrier(void){
  MemoryBarrier();
}

int lsmWin32OsShmUnmap(lsm_file *pFile, int bDelete){
  Win32File *pWin32File = (Win32File *)pFile;

  if( pWin32File->hShmFile!=NULL ){
    int i;
    for(i=0; i<pWin32File->nShm; i++){
      if( pWin32File->apShm[i]!=NULL ){
        UnmapViewOfFile(pWin32File->apShm[i]);
        pWin32File->apShm[i] = NULL;
      }
      if( pWin32File->ahShm[i]!=NULL ){
        CloseHandle(pWin32File->ahShm[i]);
        pWin32File->ahShm[i] = NULL;
      }
    }
    CloseHandle(pWin32File->hShmFile);
    pWin32File->hShmFile = 0;
    if( bDelete ){
      char *zShm = win32ShmFile(pWin32File);
      if( zShm ){ win32Delete(pWin32File->pEnv, zShm); }
      lsmFree(pWin32File->pEnv, zShm);
    }
  }
  return LSM_OK;
}

#define MX_CLOSE_ATTEMPT 3
static int lsmWin32OsClose(lsm_file *pFile){
  int rc;
  int nRetry = 0;
  Win32File *pWin32File = (Win32File *)pFile;