SQLite

Check-in [b53ab71d07]
Login

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

Overview
Comment:Minor coding fix in getting the windows platform version, when multithreading (CVS 761)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b53ab71d074ada47ce22bd161f6aee24587302af
User & Date: mike 2002-10-17 09:01:32.000
Context
2002-10-19
20:13
Fix the URL for pointing to MinGW on the homepage. (CVS 762) (check-in: 16aad98aad user: drh tags: trunk)
2002-10-17
09:01
Minor coding fix in getting the windows platform version, when multithreading (CVS 761) (check-in: b53ab71d07 user: mike tags: trunk)
00:38
fix for locking in Windows (CVS 760) (check-in: 83add34f64 user: mike tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os.c.
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
** point to the same locking structure.  The locking structure keeps
** a reference count (so we will know when to delete it) and a "cnt"
** field that tells us its internal lock status.  cnt==0 means the
** file is unlocked.  cnt==-1 means the file has an exclusive lock.
** cnt>0 means there are cnt shared locks on the file.
**
** Any attempt to lock or unlock a file first checks the locking
** structure.  The fcntl() system call is only invoked to set a 
** POSIX lock if the internal lock structure transitions between
** a locked and an unlocked state.
*/

/*
** An instance of the following structure serves as the key used
** to locate a particular lockInfo structure given its inode. 
*/
struct inodeKey {
  dev_t dev;   /* Device number */
  ino_t ino;   /* Inode number */
};

/*
** An instance of the following structure is allocated for each inode.
** A single inode can have multiple file descriptors, so each OsFile
** structure contains a pointer to an instance of this object and this
** object keeps a count of the number of OsFiles pointing to it.
*/
struct lockInfo {
  struct inodeKey key;  /* The lookup key */
  int cnt;              /* 0: unlocked.  -1: write lock.  1...: read lock. */
  int nRef;             /* Number of pointers to this structure */
};

/* 
** This hash table maps inodes (in the form of inodeKey structures) into
** pointers to lockInfo structures.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };

/*
** Given a file descriptor, locate a lockInfo structure that describes







|






|


















|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
** point to the same locking structure.  The locking structure keeps
** a reference count (so we will know when to delete it) and a "cnt"
** field that tells us its internal lock status.  cnt==0 means the
** file is unlocked.  cnt==-1 means the file has an exclusive lock.
** cnt>0 means there are cnt shared locks on the file.
**
** Any attempt to lock or unlock a file first checks the locking
** structure.  The fcntl() system call is only invoked to set a
** POSIX lock if the internal lock structure transitions between
** a locked and an unlocked state.
*/

/*
** An instance of the following structure serves as the key used
** to locate a particular lockInfo structure given its inode.
*/
struct inodeKey {
  dev_t dev;   /* Device number */
  ino_t ino;   /* Inode number */
};

/*
** An instance of the following structure is allocated for each inode.
** A single inode can have multiple file descriptors, so each OsFile
** structure contains a pointer to an instance of this object and this
** object keeps a count of the number of OsFiles pointing to it.
*/
struct lockInfo {
  struct inodeKey key;  /* The lookup key */
  int cnt;              /* 0: unlocked.  -1: write lock.  1...: read lock. */
  int nRef;             /* Number of pointers to this structure */
};

/*
** This hash table maps inodes (in the form of inodeKey structures) into
** pointers to lockInfo structures.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };

/*
** Given a file descriptor, locate a lockInfo structure that describes
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  int *pReadonly
){
#if OS_UNIX
  id->fd = open(zFilename, O_RDWR|O_CREAT, 0644);
  if( id->fd<0 ){
    id->fd = open(zFilename, O_RDONLY);
    if( id->fd<0 ){
      return SQLITE_CANTOPEN; 
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  sqliteOsEnterMutex();
  id->pLock = findLockInfo(id->fd);







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  int *pReadonly
){
#if OS_UNIX
  id->fd = open(zFilename, O_RDWR|O_CREAT, 0644);
  if( id->fd<0 ){
    id->fd = open(zFilename, O_RDONLY);
    if( id->fd<0 ){
      return SQLITE_CANTOPEN;
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  sqliteOsEnterMutex();
  id->pLock = findLockInfo(id->fd);
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  }
  return SQLITE_OK;
#endif
#if OS_WIN
  HANDLE h;
  int fileflags;
  if( delFlag ){
    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
                     | FILE_FLAG_DELETE_ON_CLOSE;
  }else{
    fileflags = FILE_FLAG_RANDOM_ACCESS;
  }
  h = CreateFile(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  }
  return SQLITE_OK;
#endif
#if OS_WIN
  HANDLE h;
  int fileflags;
  if( delFlag ){
    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
                     | FILE_FLAG_DELETE_ON_CLOSE;
  }else{
    fileflags = FILE_FLAG_RANDOM_ACCESS;
  }
  h = CreateFile(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
      int n = sqliteRandomByte() % sizeof(zChars);
      zBuf[j++] = zChars[n];
    }
    zBuf[j] = 0;
    if( !sqliteOsFileExists(zBuf) ) break;
  }
#endif
  return SQLITE_OK; 
}

/*
** Close a file
*/
int sqliteOsClose(OsFile *id){
#if OS_UNIX







|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
      int n = sqliteRandomByte() % sizeof(zChars);
      zBuf[j++] = zChars[n];
    }
    zBuf[j] = 0;
    if( !sqliteOsFileExists(zBuf) ) break;
  }
#endif
  return SQLITE_OK;
}

/*
** Close a file
*/
int sqliteOsClose(OsFile *id){
#if OS_UNIX
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
#define MX_LOCKBYTE 0xFFF0

#if OS_WIN

// get the platform id to decide how to calculate the lock offset

int mkPlatformId(void){
 
 static long init=0;


 static int pid=VER_PLATFORM_WIN32_WINDOWS;
 OSVERSIONINFOA info;	
 
 if (!init) {
  if (InterlockedIncrement(&init)==1)
   {
    info.dwOSVersionInfoSize=sizeof(info);
   if (GetVersionEx(&info)) pid=info.dwPlatformId;

   }


  } 
 return pid;  
}

// locks and unlocks beyond eof. uses platformid to move the lock as far as possible.
int mklock(HANDLE h, WORD base, WORD size)
{
 if (mkPlatformId()==VER_PLATFORM_WIN32_WINDOWS)
  return LockFile(h,0xFFFF0000+base,0,size,0);







|

>
>

|
|
|
|


|
>

>
>
|
|







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
#define MX_LOCKBYTE 0xFFF0

#if OS_WIN

// get the platform id to decide how to calculate the lock offset

int mkPlatformId(void){

 static long init=0;
 static long lock=0;

 static int pid=VER_PLATFORM_WIN32_WINDOWS;
 OSVERSIONINFOA info;

 while (!init) {
  if (InterlockedIncrement(&lock)==1)
   {
    info.dwOSVersionInfoSize=sizeof(info);
    if (GetVersionEx(&info)) pid=info.dwPlatformId;
    init=1;
   }
  else
   Sleep(1);
  }
 return pid;
}

// locks and unlocks beyond eof. uses platformid to move the lock as far as possible.
int mklock(HANDLE h, WORD base, WORD size)
{
 if (mkPlatformId()==VER_PLATFORM_WIN32_WINDOWS)
  return LockFile(h,0xFFFF0000+base,0,size,0);
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  return UnlockFile(h,0xFFFF0000+base,0,size,0);
 else
  return UnlockFile(h,base,0xFFFFFFFF,size,0);
}

//obtain the sync lock on a handle

void synclock(HANDLE h){ 
 while (!mklock(h,0,1)) Sleep(1);
}

void syncunlock(HANDLE h){ 
 mkunlock(h,0,1);
}

#endif

/*
** Change the status of the lock on the file "id" to be a readlock.







|



|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  return UnlockFile(h,0xFFFF0000+base,0,size,0);
 else
  return UnlockFile(h,base,0xFFFFFFFF,size,0);
}

//obtain the sync lock on a handle

void synclock(HANDLE h){
 while (!mklock(h,0,1)) Sleep(1);
}

void syncunlock(HANDLE h){
 mkunlock(h,0,1);
}

#endif

/*
** Change the status of the lock on the file "id" to be a readlock.
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
#if OS_WIN
  int rc;
  if( id->locked>0 ){
    rc = SQLITE_OK;
  }else{
    int lk = (sqliteRandomInteger() & 0x7ffffff)%MX_LOCKBYTE + 1;
    int res;
    
    synclock(id->h);
    if (id->locked<0) mkunlock(id->h,1,MX_LOCKBYTE); // release write lock if we have it
    res=mklock(id->h,lk,1);
    syncunlock(id->h);
    
    if( res ){
      id->locked = lk;
      rc = SQLITE_OK;
    }else{
      rc = SQLITE_BUSY;
    }
  }







|




|







730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
#if OS_WIN
  int rc;
  if( id->locked>0 ){
    rc = SQLITE_OK;
  }else{
    int lk = (sqliteRandomInteger() & 0x7ffffff)%MX_LOCKBYTE + 1;
    int res;

    synclock(id->h);
    if (id->locked<0) mkunlock(id->h,1,MX_LOCKBYTE); // release write lock if we have it
    res=mklock(id->h,lk,1);
    syncunlock(id->h);

    if( res ){
      id->locked = lk;
      rc = SQLITE_OK;
    }else{
      rc = SQLITE_BUSY;
    }
  }
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
#endif
#if OS_WIN
  int rc;
  if( id->locked<0 ){
    rc = SQLITE_OK;
  }else{
    int res;
    
    synclock(id->h);
    if (id->locked>0) mkunlock(id->h,id->locked,1); // release read lock
    res=mklock(id->h,1,MX_LOCKBYTE);
    syncunlock(id->h);
   
    if(res){
      id->locked = -1;
      rc = SQLITE_OK;
    }else{
      rc = SQLITE_BUSY;
    }
  }







|




|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
#endif
#if OS_WIN
  int rc;
  if( id->locked<0 ){
    rc = SQLITE_OK;
  }else{
    int res;

    synclock(id->h);
    if (id->locked>0) mkunlock(id->h,id->locked,1); // release read lock
    res=mklock(id->h,1,MX_LOCKBYTE);
    syncunlock(id->h);

    if(res){
      id->locked = -1;
      rc = SQLITE_OK;
    }else{
      rc = SQLITE_BUSY;
    }
  }