⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_os2.c

📁 这是一个开源的数据库系统,值得学习啊, 里面用了SQL语句,与微软的SQL SERVIER,差不了多少
💻 C
📖 第 1 页 / 共 2 页
字号:
    if( res == NO_ERROR ){      newLocktype = SHARED_LOCK;    }  }  /* Acquire a RESERVED lock  */  if( locktype==RESERVED_LOCK && res ){    assert( pFile->locktype==SHARED_LOCK );    LockArea.lOffset = RESERVED_BYTE;    LockArea.lRange = 1L;    UnlockArea.lOffset = 0L;    UnlockArea.lRange = 0L;    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );    if( res == NO_ERROR ){      newLocktype = RESERVED_LOCK;    }  }  /* Acquire a PENDING lock  */  if( locktype==EXCLUSIVE_LOCK && res ){    newLocktype = PENDING_LOCK;    gotPendingLock = 0;  }  /* Acquire an EXCLUSIVE lock  */  if( locktype==EXCLUSIVE_LOCK && res ){    assert( pFile->locktype>=SHARED_LOCK );    res = unlockReadLock(pFile);    OSTRACE2( "unreadlock = %d\n", res );    LockArea.lOffset = SHARED_FIRST;    LockArea.lRange = SHARED_SIZE;    UnlockArea.lOffset = 0L;    UnlockArea.lRange = 0L;    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );    if( res == NO_ERROR ){      newLocktype = EXCLUSIVE_LOCK;    }else{      OSTRACE2( "error-code = %d\n", res );    }  }  /* If we are holding a PENDING lock that ought to be released, then  ** release it now.  */  if( gotPendingLock && locktype==SHARED_LOCK ){    LockArea.lOffset = 0L;    LockArea.lRange = 0L;    UnlockArea.lOffset = PENDING_BYTE;    UnlockArea.lRange = 1L;    DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );  }  /* Update the state of the lock has held in the file descriptor then  ** return the appropriate result code.  */  if( res == NO_ERROR ){    rc = SQLITE_OK;  }else{    OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,           locktype, newLocktype );    rc = SQLITE_BUSY;  }  pFile->locktype = newLocktype;  return rc;}/*** This routine checks if there is a RESERVED lock held on the specified** file by this or any other process. If such a lock is held, return** non-zero, otherwise zero.*/int os2CheckReservedLock( OsFile *id ){  APIRET rc = NO_ERROR;  os2File *pFile = (os2File*)id;  assert( pFile!=0 );  if( pFile->locktype>=RESERVED_LOCK ){    rc = 1;    OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, rc );  }else{    FILELOCK  LockArea,              UnlockArea;    memset(&LockArea, 0, sizeof(LockArea));    memset(&UnlockArea, 0, sizeof(UnlockArea));    LockArea.lOffset = RESERVED_BYTE;    LockArea.lRange = 1L;    UnlockArea.lOffset = 0L;    UnlockArea.lRange = 0L;    rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );    if( rc == NO_ERROR ){      LockArea.lOffset = 0L;      LockArea.lRange = 0L;      UnlockArea.lOffset = RESERVED_BYTE;      UnlockArea.lRange = 1L;      rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );    }    OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc );  }  return rc;}/*** Lower the locking level on file descriptor id to locktype.  locktype** must be either NO_LOCK or SHARED_LOCK.**** If the locking level of the file descriptor is already at or below** the requested locking level, this routine is a no-op.**** It is not possible for this routine to fail if the second argument** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine** might return SQLITE_IOERR;*/int os2Unlock( OsFile *id, int locktype ){  int type;  APIRET rc = SQLITE_OK;  os2File *pFile = (os2File*)id;  FILELOCK  LockArea,            UnlockArea;  memset(&LockArea, 0, sizeof(LockArea));  memset(&UnlockArea, 0, sizeof(UnlockArea));  assert( pFile!=0 );  assert( locktype<=SHARED_LOCK );  OSTRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype );  type = pFile->locktype;  if( type>=EXCLUSIVE_LOCK ){    LockArea.lOffset = 0L;    LockArea.lRange = 0L;    UnlockArea.lOffset = SHARED_FIRST;    UnlockArea.lRange = SHARED_SIZE;    DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );    if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){      /* This should never happen.  We should always be able to      ** reacquire the read lock */      rc = SQLITE_IOERR;    }  }  if( type>=RESERVED_LOCK ){    LockArea.lOffset = 0L;    LockArea.lRange = 0L;    UnlockArea.lOffset = RESERVED_BYTE;    UnlockArea.lRange = 1L;    DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );  }  if( locktype==NO_LOCK && type>=SHARED_LOCK ){    unlockReadLock(pFile);  }  if( type>=PENDING_LOCK ){    LockArea.lOffset = 0L;    LockArea.lRange = 0L;    UnlockArea.lOffset = PENDING_BYTE;    UnlockArea.lRange = 1L;    DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );  }  pFile->locktype = locktype;  return rc;}/*** Turn a relative pathname into a full pathname.  Return a pointer** to the full pathname stored in space obtained from sqliteMalloc().** The calling function is responsible for freeing this space once it** is no longer needed.*/char *sqlite3Os2FullPathname( const char *zRelative ){  char *zFull = 0;  if( strchr(zRelative, ':') ){    sqlite3SetString( &zFull, zRelative, (char*)0 );  }else{    ULONG ulDriveNum = 0;    ULONG ulDriveMap = 0;    ULONG cbzBufLen = SQLITE_TEMPNAME_SIZE;    char zDrive[2];    char *zBuff;    zBuff = sqliteMalloc( cbzBufLen );    if( zBuff != 0 ){      DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );      if( DosQueryCurrentDir( ulDriveNum, (PBYTE)zBuff, &cbzBufLen ) == NO_ERROR ){        sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) );        sqlite3SetString( &zFull, zDrive, ":\\", zBuff,                          "\\", zRelative, (char*)0 );      }      sqliteFree( zBuff );    }  }  return zFull;}/*** The fullSync option is meaningless on os2, or correct me if I'm wrong.  This is a no-op.** From os_unix.c: Change the value of the fullsync flag in the given file descriptor.** From os_unix.c: ((unixFile*)id)->fullSync = v;*/static void os2SetFullSync( OsFile *id, int v ){  return;}/*** Return the underlying file handle for an OsFile*/static int os2FileHandle( OsFile *id ){  return (int)((os2File*)id)->h;}/*** Return an integer that indices the type of lock currently held** by this handle.  (Used for testing and analysis only.)*/static int os2LockState( OsFile *id ){  return ((os2File*)id)->locktype;}/*** Return the sector size in bytes of the underlying block device for** the specified file. This is almost always 512 bytes, but may be** larger for some devices.**** SQLite code assumes this function cannot fail. It also assumes that** if two files are created in the same file-system directory (i.e.** a database and it's journal file) that the sector size will be the** same for both.*/static int os2SectorSize(OsFile *id){  return SQLITE_DEFAULT_SECTOR_SIZE;}/*** This vector defines all the methods that can operate on an OsFile** for os2.*/static const IoMethod sqlite3Os2IoMethod = {  os2Close,  os2OpenDirectory,  os2Read,  os2Write,  os2Seek,  os2Truncate,  os2Sync,  os2SetFullSync,  os2FileHandle,  os2FileSize,  os2Lock,  os2Unlock,  os2LockState,  os2CheckReservedLock,  os2SectorSize,};/*** Allocate memory for an OsFile.  Initialize the new OsFile** to the value given in pInit and return a pointer to the new** OsFile.  If we run out of memory, close the file and return NULL.*/int allocateOs2File( os2File *pInit, OsFile **pld ){  os2File *pNew;  pNew = sqliteMalloc( sizeof(*pNew) );  if( pNew==0 ){    DosClose( pInit->h );    *pld = 0;    return SQLITE_NOMEM;  }else{    *pNew = *pInit;    pNew->pMethod = &sqlite3Os2IoMethod;    pNew->locktype = NO_LOCK;    *pld = (OsFile*)pNew;    OpenCounter(+1);    return SQLITE_OK;  }}#endif /* SQLITE_OMIT_DISKIO *//***************************************************************************** Everything above deals with file I/O.  Everything that follows deals** with other miscellanous aspects of the operating system interface****************************************************************************/#ifndef SQLITE_OMIT_LOAD_EXTENSION/*** Interfaces for opening a shared library, finding entry points** within the shared library, and closing the shared library.*/void *sqlite3Os2Dlopen(const char *zFilename){  UCHAR loadErr[256];  HMODULE hmod;  APIRET rc;  rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilename, &hmod);  if (rc != NO_ERROR) return 0;  return (void*)hmod;}void *sqlite3Os2Dlsym(void *pHandle, const char *zSymbol){  PFN pfn;  APIRET rc;  rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);  if (rc != NO_ERROR) {    /* if the symbol itself was not found, search again for the same     * symbol with an extra underscore, that might be needed depending     * on the calling convention */    char _zSymbol[256] = "_";    strncat(_zSymbol, zSymbol, 255);    rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);  }  if (rc != NO_ERROR) return 0;  return (void *)pfn;}int sqlite3Os2Dlclose(void *pHandle){  return DosFreeModule((HMODULE)pHandle);}#endif /* SQLITE_OMIT_LOAD_EXTENSION *//*** Get information to seed the random number generator.  The seed** is written into the buffer zBuf[256].  The calling function must** supply a sufficiently large buffer.*/int sqlite3Os2RandomSeed( char *zBuf ){  /* We have to initialize zBuf to prevent valgrind from reporting  ** errors.  The reports issued by valgrind are incorrect - we would  ** prefer that the randomness be increased by making use of the  ** uninitialized space in zBuf - but valgrind errors tend to worry  ** some users.  Rather than argue, it seems easier just to initialize  ** the whole array and silence valgrind, even if that means less randomness  ** in the random seed.  **  ** When testing, initializing zBuf[] to zero is all we do.  That means  ** that we always use the same random number sequence. This makes the  ** tests repeatable.  */  memset( zBuf, 0, 256 );  DosGetDateTime( (PDATETIME)zBuf );  return SQLITE_OK;}/*** Sleep for a little while.  Return the amount of time slept.*/int sqlite3Os2Sleep( int ms ){  DosSleep( ms );  return ms;}/*** Static variables used for thread synchronization*/static int inMutex = 0;#ifdef SQLITE_OS2_THREADSstatic ULONG mutexOwner;#endif/*** The following pair of routines implement mutual exclusion for** multi-threaded processes.  Only a single thread is allowed to** executed code that is surrounded by EnterMutex() and LeaveMutex().**** SQLite uses only a single Mutex.  There is not much critical** code and what little there is executes quickly and without blocking.*/void sqlite3Os2EnterMutex(){#ifdef SQLITE_OS2_THREADS  PTIB ptib;  DosEnterCritSec();  DosGetInfoBlocks( &ptib, NULL );  mutexOwner = ptib->tib_ptib2->tib2_ultid;#endif  assert( !inMutex );  inMutex = 1;}void sqlite3Os2LeaveMutex(){#ifdef SQLITE_OS2_THREADS  PTIB ptib;#endif  assert( inMutex );  inMutex = 0;#ifdef SQLITE_OS2_THREADS  DosGetInfoBlocks( &ptib, NULL );  assert( mutexOwner == ptib->tib_ptib2->tib2_ultid );  DosExitCritSec();#endif}/*** Return TRUE if the mutex is currently held.**** If the thisThreadOnly parameter is true, return true if and only if the** calling thread holds the mutex.  If the parameter is false, return** true if any thread holds the mutex.*/int sqlite3Os2InMutex( int thisThreadOnly ){#ifdef SQLITE_OS2_THREADS  PTIB ptib;  DosGetInfoBlocks( &ptib, NULL );  return inMutex>0 && (thisThreadOnly==0 || mutexOwner==ptib->tib_ptib2->tib2_ultid);#else  return inMutex>0;#endif}/*** The following variable, if set to a non-zero value, becomes the result** returned from sqlite3OsCurrentTime().  This is used for testing.*/#ifdef SQLITE_TESTint sqlite3_current_time = 0;#endif/*** Find the current time (in Universal Coordinated Time).  Write the** current time and date as a Julian Day number into *prNow and** return 0.  Return 1 if the time and date cannot be found.*/int sqlite3Os2CurrentTime( double *prNow ){  double now;  USHORT second, minute, hour,         day, month, year;  DATETIME dt;  DosGetDateTime( &dt );  second = (USHORT)dt.seconds;  minute = (USHORT)dt.minutes + dt.timezone;  hour = (USHORT)dt.hours;  day = (USHORT)dt.day;  month = (USHORT)dt.month;  year = (USHORT)dt.year;  /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html     http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */  /* Calculate the Julian days */  now = day - 32076 +    1461*(year + 4800 + (month - 14)/12)/4 +    367*(month - 2 - (month - 14)/12*12)/12 -    3*((year + 4900 + (month - 14)/12)/100)/4;  /* Add the fractional hours, mins and seconds */  now += (hour + 12.0)/24.0;  now += minute/1440.0;  now += second/86400.0;  *prNow = now;#ifdef SQLITE_TEST  if( sqlite3_current_time ){    *prNow = sqlite3_current_time/86400.0 + 2440587.5;  }#endif  return 0;}/*** Remember the number of thread-specific-data blocks allocated.** Use this to verify that we are not leaking thread-specific-data.** Ticket #1601*/#ifdef SQLITE_TESTint sqlite3_tsd_count = 0;# define TSD_COUNTER_INCR InterlockedIncrement( &sqlite3_tsd_count )# define TSD_COUNTER_DECR InterlockedDecrement( &sqlite3_tsd_count )#else# define TSD_COUNTER_INCR  /* no-op */# define TSD_COUNTER_DECR  /* no-op */#endif/*** If called with allocateFlag>1, then return a pointer to thread** specific data for the current thread.  Allocate and zero the** thread-specific data if it does not already exist necessary.**** If called with allocateFlag==0, then check the current thread** specific data.  Return it if it exists.  If it does not exist,** then return NULL.**** If called with allocateFlag<0, check to see if the thread specific** data is allocated and is all zero.  If it is then deallocate it.** Return a pointer to the thread specific data or NULL if it is** unallocated or gets deallocated.*/ThreadData *sqlite3Os2ThreadSpecificData( int allocateFlag ){  static ThreadData **s_ppTsd = NULL;  static const ThreadData zeroData = {0, 0, 0};  ThreadData *pTsd;  if( !s_ppTsd ){    sqlite3OsEnterMutex();    if( !s_ppTsd ){      PULONG pul;      APIRET rc = DosAllocThreadLocalMemory(1, &pul);      if( rc != NO_ERROR ){        sqlite3OsLeaveMutex();        return 0;      }      s_ppTsd = (ThreadData **)pul;    }    sqlite3OsLeaveMutex();  }  pTsd = *s_ppTsd;  if( allocateFlag>0 ){    if( !pTsd ){      pTsd = sqlite3OsMalloc( sizeof(zeroData) );      if( pTsd ){        *pTsd = zeroData;        *s_ppTsd = pTsd;        TSD_COUNTER_INCR;      }    }  }else if( pTsd!=0 && allocateFlag<0              && memcmp( pTsd, &zeroData, sizeof(ThreadData) )==0 ){    sqlite3OsFree(pTsd);    *s_ppTsd = NULL;    TSD_COUNTER_DECR;    pTsd = 0;  }  return pTsd;}#endif /* OS_OS2 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -