/ Check-in [38ec4141]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix issues in the POSIX and Win32 interfaces for lsm1.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 38ec41416679e8280d77c8a4913aa6a321784b1237a3fe409b8e256c5f4513de
User & Date: mistachkin 2017-06-29 19:08:52
Context
2017-06-29
20:23
Avoid reading or writing the 32 locking bytes at the end of the first meta-page of an LSM database. check-in: 3ed6877f user: dan tags: trunk
20:13
Avoid reading or writing the 32 locking bytes at the end of the first meta-page of an LSM database. Closed-Leaf check-in: 2b5df3e8 user: dan tags: lsm-metapage-fix
19:08
Fix issues in the POSIX and Win32 interfaces for lsm1. check-in: 38ec4141 user: mistachkin tags: trunk
17:27
Edit comments in sqlite.h.in used for generating documentation, to improve the description of the new sqlite3_prepare_v3() interfaces, and other miscellaneous cleanup. No changes to executable code. check-in: 284707a7 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/lsm1/lsm_unix.c.

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  assert( eType>=0 && eType<array_size(aType) );
  assert( iLock>0 && iLock<=32 );

  memset(&lock, 0, sizeof(lock));
  lock.l_whence = SEEK_SET;
  lock.l_len = nLock;
  lock.l_type = aType[eType];
  lock.l_start = (4096-iLock);

  if( fcntl(p->fd, F_GETLK, &lock) ){
    rc = LSM_IOERR_BKPT;
  }else if( lock.l_type!=F_UNLCK ){
    rc = LSM_BUSY;
  }








|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  assert( eType>=0 && eType<array_size(aType) );
  assert( iLock>0 && iLock<=32 );

  memset(&lock, 0, sizeof(lock));
  lock.l_whence = SEEK_SET;
  lock.l_len = nLock;
  lock.l_type = aType[eType];
  lock.l_start = (4096-iLock-nLock+1);

  if( fcntl(p->fd, F_GETLK, &lock) ){
    rc = LSM_IOERR_BKPT;
  }else if( lock.l_type!=F_UNLCK ){
    rc = LSM_BUSY;
  }

Changes to ext/lsm1/lsm_win32.c.

280
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
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
...
621
622
623
624
625
626
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
...
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
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED overlapped;  /* The offset for WriteFile. */
  u8 *aRem = (u8 *)pData; /* Data yet to be written */
  int nRem = nData;       /* Number of bytes yet to be written */
  int nRetry = 0;         /* Number of retrys */

  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(iOff & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
  while( nRem>0 ){
    DWORD nWrite = 0; /* Bytes written using WriteFile */
    if( !WriteFile(pWin32File->hFile, aRem, nRem, &nWrite, &overlapped) ){
      if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
      break;
    }
    assert( nWrite==0 || nWrite<=(DWORD)nRem );
    if( nWrite==0 || nWrite>(DWORD)nRem ){
      break;
    }
    iOff += nWrite;
    overlapped.Offset = (LONG)(iOff & 0xffffffff);
    overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
    aRem += nWrite;
    nRem -= nWrite;
  }
  if( nRem!=0 ) return LSM_IOERR_BKPT;
  return LSM_OK;
}

................................................................................
){
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED overlapped; /* The offset for ReadFile */
  DWORD nRead = 0;       /* Bytes read using ReadFile */
  int nRetry = 0;        /* Number of retrys */

  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(iOff & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7fffffff);
  while( !ReadFile(pWin32File->hFile, pData, nData, &nRead, &overlapped) &&
         GetLastError()!=ERROR_HANDLE_EOF ){
    if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
    return LSM_IOERR_BKPT;
  }
  if( nRead<(DWORD)nData ){
    /* Unread parts of the buffer must be zero-filled */
................................................................................

  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;
      }
................................................................................
  assert( LSM_LOCK_EXCL==2 );
  assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL );
  assert( nLock>=0 );
  assert( iLock>0 && iLock<=32 );

  if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK;
  memset(&ovlp, 0, sizeof(OVERLAPPED));
  ovlp.Offset = (4096-iLock);
  if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){
    if( win32IsLockBusy(GetLastError()) ){
      return LSM_BUSY;
    }else{
      return LSM_IOERR_BKPT;
    }
  }
................................................................................
  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;
    LPHANDLE ahNew;
    LPVOID *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);
................................................................................
    pWin32File->ahShm = ahNew;
    pWin32File->apShm = apNew;
    pWin32File->nShm = nNew;
  }

  if( pWin32File->ahShm[iChunk]==NULL ){
    HANDLE hMap;

    hMap = CreateFileMappingW(pWin32File->hShmFile, NULL, PAGE_READWRITE, 0,
                              (DWORD)sz, NULL);
    if( hMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->ahShm[iChunk] = hMap;
  }
  if( pWin32File->apShm[iChunk]==NULL ){
    int iOffset = iChunk * sz;
    int iOffsetShift = iOffset % pWin32File->sysInfo.dwAllocationGranularity;
    LPVOID pMap;
    pMap = MapViewOfFile(pWin32File->ahShm[iChunk],
                         FILE_MAP_WRITE | FILE_MAP_READ, 0,
                         iOffset - iOffsetShift, sz + iOffsetShift);
    if( pMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->apShm[iChunk] = pMap;
  }




  *ppShm = pWin32File->apShm[iChunk];

  return LSM_OK;
}

void lsmWin32OsShmBarrier(void){
  MemoryBarrier();
}








|
|











|
|







 







|
|







 







<







 







|







 







>
>
>
>








<
<







 







>

|






<
<









>
>
>
>
|
>







280
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
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
542
543
544
545
546
547
548

549
550
551
552
553
554
555
...
620
621
622
623
624
625
626
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
...
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
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED overlapped;  /* The offset for WriteFile. */
  u8 *aRem = (u8 *)pData; /* Data yet to be written */
  int nRem = nData;       /* Number of bytes yet to be written */
  int nRetry = 0;         /* Number of retrys */

  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(iOff & 0XFFFFFFFF);
  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7FFFFFFF);
  while( nRem>0 ){
    DWORD nWrite = 0; /* Bytes written using WriteFile */
    if( !WriteFile(pWin32File->hFile, aRem, nRem, &nWrite, &overlapped) ){
      if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
      break;
    }
    assert( nWrite==0 || nWrite<=(DWORD)nRem );
    if( nWrite==0 || nWrite>(DWORD)nRem ){
      break;
    }
    iOff += nWrite;
    overlapped.Offset = (LONG)(iOff & 0xFFFFFFFF);
    overlapped.OffsetHigh = (LONG)((iOff>>32) & 0x7FFFFFFF);
    aRem += nWrite;
    nRem -= nWrite;
  }
  if( nRem!=0 ) return LSM_IOERR_BKPT;
  return LSM_OK;
}

................................................................................
){
  Win32File *pWin32File = (Win32File *)pFile;
  OVERLAPPED overlapped; /* The offset for ReadFile */
  DWORD nRead = 0;       /* Bytes read using ReadFile */
  int nRetry = 0;        /* Number of retrys */

  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(iOff & 0XFFFFFFFF);
  overlapped.OffsetHigh = (LONG)((iOff>>32) & 0X7FFFFFFF);
  while( !ReadFile(pWin32File->hFile, pData, nData, &nRead, &overlapped) &&
         GetLastError()!=ERROR_HANDLE_EOF ){
    if( win32RetryIoerr(pWin32File->pEnv, &nRetry) ) continue;
    return LSM_IOERR_BKPT;
  }
  if( nRead<(DWORD)nData ){
    /* Unread parts of the buffer must be zero-filled */
................................................................................

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


    do {
      attr = GetFileAttributesW(zConverted);
      if ( attr==INVALID_FILE_ATTRIBUTES ){
        rc = LSM_IOERR_BKPT;
        break;
      }
................................................................................
  assert( LSM_LOCK_EXCL==2 );
  assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL );
  assert( nLock>=0 );
  assert( iLock>0 && iLock<=32 );

  if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK;
  memset(&ovlp, 0, sizeof(OVERLAPPED));
  ovlp.Offset = (4096-iLock-nLock+1);
  if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){
    if( win32IsLockBusy(GetLastError()) ){
      return LSM_BUSY;
    }else{
      return LSM_IOERR_BKPT;
    }
  }
................................................................................
  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;
  int iOffset = iChunk * sz;
  int iOffsetShift = iOffset % pWin32File->sysInfo.dwAllocationGranularity;
  int nNew = iChunk + 1;
  lsm_i64 nReq = nNew * sz;

  *ppShm = NULL;
  assert( sz>=0 );
  assert( sz==LSM_SHM_CHUNK_SIZE );
  if( iChunk>=pWin32File->nShm ){
    int i;
    LPHANDLE ahNew;
    LPVOID *apNew;


    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);
................................................................................
    pWin32File->ahShm = ahNew;
    pWin32File->apShm = apNew;
    pWin32File->nShm = nNew;
  }

  if( pWin32File->ahShm[iChunk]==NULL ){
    HANDLE hMap;
    assert( nReq<=0xFFFFFFFF );
    hMap = CreateFileMappingW(pWin32File->hShmFile, NULL, PAGE_READWRITE, 0,
                              (DWORD)nReq, NULL);
    if( hMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->ahShm[iChunk] = hMap;
  }
  if( pWin32File->apShm[iChunk]==NULL ){


    LPVOID pMap;
    pMap = MapViewOfFile(pWin32File->ahShm[iChunk],
                         FILE_MAP_WRITE | FILE_MAP_READ, 0,
                         iOffset - iOffsetShift, sz + iOffsetShift);
    if( pMap==NULL ){
      return LSM_IOERR_BKPT;
    }
    pWin32File->apShm[iChunk] = pMap;
  }
  if( iOffsetShift!=0 ){
    char *p = (char *)pWin32File->apShm[iChunk];
    *ppShm = (void *)&p[iOffsetShift];
  }else{
    *ppShm = pWin32File->apShm[iChunk];
  }
  return LSM_OK;
}

void lsmWin32OsShmBarrier(void){
  MemoryBarrier();
}