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

📄 os_unix.c

📁 sqlite的最新源码 This ZIP archive contains preprocessed C code for the SQLite library as individual sour
💻 C
📖 第 1 页 / 共 5 页
字号:
#define LOCKING_STYLE_AFP          5#define LOCKING_STYLE_NAMEDSEM     6/*** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK*/#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))/*** Helper functions to obtain and relinquish the global mutex.*/static void enterMutex(void){  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));}static void leaveMutex(void){  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));}#if SQLITE_THREADSAFE/*** This variable records whether or not threads can override each others** locks.****    0:  No.  Threads cannot override each others locks.**    1:  Yes.  Threads can override each others locks.**   -1:  We don't know yet.**** On some systems, we know at compile-time if threads can override each** others locks.  On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro** will be set appropriately.  On other systems, we have to check at** runtime.  On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is** undefined.**** This variable normally has file scope only.  But during testing, we make** it a global so that the test code can change its value in order to verify** that the right stuff happens in either case.*/#ifndef SQLITE_THREAD_OVERRIDE_LOCK# define SQLITE_THREAD_OVERRIDE_LOCK -1#endif#ifdef SQLITE_TESTint threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;#elsestatic int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;#endif/*** This structure holds information passed into individual test** threads by the testThreadLockingBehavior() routine.*/struct threadTestData {  int fd;                /* File to be locked */  struct flock lock;     /* The locking operation */  int result;            /* Result of the locking operation */};#ifdef SQLITE_LOCK_TRACE/*** Print out information about all locking operations.**** This routine is used for troubleshooting locks on multithreaded** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE** command-line option on the compiler.  This code is normally** turned off.*/static int lockTrace(int fd, int op, struct flock *p){  char *zOpName, *zType;  int s;  int savedErrno;  if( op==F_GETLK ){    zOpName = "GETLK";  }else if( op==F_SETLK ){    zOpName = "SETLK";  }else{    s = fcntl(fd, op, p);    sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);    return s;  }  if( p->l_type==F_RDLCK ){    zType = "RDLCK";  }else if( p->l_type==F_WRLCK ){    zType = "WRLCK";  }else if( p->l_type==F_UNLCK ){    zType = "UNLCK";  }else{    assert( 0 );  }  assert( p->l_whence==SEEK_SET );  s = fcntl(fd, op, p);  savedErrno = errno;  sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",     threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,     (int)p->l_pid, s);  if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){    struct flock l2;    l2 = *p;    fcntl(fd, F_GETLK, &l2);    if( l2.l_type==F_RDLCK ){      zType = "RDLCK";    }else if( l2.l_type==F_WRLCK ){      zType = "WRLCK";    }else if( l2.l_type==F_UNLCK ){      zType = "UNLCK";    }else{      assert( 0 );    }    sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",       zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);  }  errno = savedErrno;  return s;}#define fcntl lockTrace#endif /* SQLITE_LOCK_TRACE */#ifdef __linux__/*** This function is used as the main routine for a thread launched by** testThreadLockingBehavior(). It tests whether the shared-lock obtained** by the main thread in testThreadLockingBehavior() conflicts with a** hypothetical write-lock obtained by this thread on the same file.**** The write-lock is not actually acquired, as this is not possible if ** the file is open in read-only mode (see ticket #3472).*/ static void *threadLockingTest(void *pArg){  struct threadTestData *pData = (struct threadTestData*)pArg;  pData->result = fcntl(pData->fd, F_GETLK, &pData->lock);  return pArg;}/*** This procedure attempts to determine whether or not threads** can override each others locks then sets the ** threadsOverrideEachOthersLocks variable appropriately.*/static void testThreadLockingBehavior(int fd_orig){  int fd;  int rc;  struct threadTestData d;  struct flock l;  pthread_t t;  fd = dup(fd_orig);  if( fd<0 ) return;  memset(&l, 0, sizeof(l));  l.l_type = F_RDLCK;  l.l_len = 1;  l.l_start = 0;  l.l_whence = SEEK_SET;  rc = fcntl(fd_orig, F_SETLK, &l);  if( rc!=0 ) return;  memset(&d, 0, sizeof(d));  d.fd = fd;  d.lock = l;  d.lock.l_type = F_WRLCK;  pthread_create(&t, 0, threadLockingTest, &d);  pthread_join(t, 0);  close(fd);  if( d.result!=0 ) return;  threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);}#else/*** On anything other than linux, assume threads override each others locks.*/static void testThreadLockingBehavior(int fd_orig){  threadsOverrideEachOthersLocks = 1;}#endif /* __linux__ */#endif /* SQLITE_THREADSAFE *//*** Release a lockInfo structure previously allocated by findLockInfo().*/static void releaseLockInfo(struct lockInfo *pLock){  if( pLock ){    pLock->nRef--;    if( pLock->nRef==0 ){      if( pLock->pPrev ){        assert( pLock->pPrev->pNext==pLock );        pLock->pPrev->pNext = pLock->pNext;      }else{        assert( lockList==pLock );        lockList = pLock->pNext;      }      if( pLock->pNext ){        assert( pLock->pNext->pPrev==pLock );        pLock->pNext->pPrev = pLock->pPrev;      }      sqlite3_free(pLock);    }  }}/*** Release a openCnt structure previously allocated by findLockInfo().*/static void releaseOpenCnt(struct openCnt *pOpen){  if( pOpen ){    pOpen->nRef--;    if( pOpen->nRef==0 ){      if( pOpen->pPrev ){        assert( pOpen->pPrev->pNext==pOpen );        pOpen->pPrev->pNext = pOpen->pNext;      }else{        assert( openList==pOpen );        openList = pOpen->pNext;      }      if( pOpen->pNext ){        assert( pOpen->pNext->pPrev==pOpen );        pOpen->pNext->pPrev = pOpen->pPrev;      }      sqlite3_free(pOpen->aPending);      sqlite3_free(pOpen);    }  }}#if IS_VXWORKS/*** Implementation of a realpath() like function for vxWorks** to determine canonical path name from given name. It does** not support symlinks. Neither does it handle volume prefixes.*/char *vxrealpath(const char *pathname, int dostat){  struct stat sbuf;  int len;  char *where, *ptr, *last;  char *result, *curpath, *workpath, *namebuf;  len = pathconf(pathname, _PC_PATH_MAX);  if( len<0 ){    len = PATH_MAX;  }  result = sqlite3_malloc(len * 4);  if( !result ){    return 0;  }  curpath = result + len;  workpath = curpath + len;  namebuf = workpath + len;  strcpy(curpath, pathname);  if( *pathname!='/' ){    if( !getcwd(workpath, len) ){      sqlite3_free(result);      return 0;    }  }else{    *workpath = '\0';  }  where = curpath;  while( *where ){    if( !strcmp(where, ".") ){      where++;      continue;    }    if( !strncmp(where, "./", 2) ){      where += 2;      continue;    }    if( !strncmp(where, "../", 3) ){      where += 3;      ptr = last = workpath;      while( *ptr ){        if( *ptr=='/' ){          last = ptr;        }        ptr++;      }      *last = '\0';      continue;    }    ptr = strchr(where, '/');    if( !ptr ){      ptr = where + strlen(where) - 1;    }else{      *ptr = '\0';    }    strcpy(namebuf, workpath);    for( last = namebuf; *last; last++ ){      continue;    }    if( *--last!='/' ){      strcat(namebuf, "/");    }    strcat(namebuf, where);    where = ++ptr;    if( dostat ){      if( stat(namebuf, &sbuf)==-1 ){        sqlite3_free(result);        return 0;      }      if( (sbuf.st_mode & S_IFDIR)==S_IFDIR ){        strcpy(workpath, namebuf);        continue;      }      if( *where ){        sqlite3_free(result);        return 0;      }    }    strcpy(workpath, namebuf);  }  strcpy(result, workpath);  return result;}#endif#if SQLITE_ENABLE_LOCKING_STYLE/*** Tests a byte-range locking query to see if byte range locks are ** supported, if not we fall back to dotlockLockingStyle.** On vxWorks we fall back to namedsemLockingStyle.*/static int testLockingStyle(int fd){  struct flock lockInfo;  /* Test byte-range lock using fcntl(). If the call succeeds,   ** assume that the file-system supports POSIX style locks.   */  lockInfo.l_len = 1;  lockInfo.l_start = 0;  lockInfo.l_whence = SEEK_SET;  lockInfo.l_type = F_RDLCK;  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {    return LOCKING_STYLE_POSIX;  }    /* Testing for flock() can give false positives.  So if if the above   ** test fails, then we fall back to using dot-file style locking (or  ** named-semaphore locking on vxworks).  */  return (IS_VXWORKS ? LOCKING_STYLE_NAMEDSEM : LOCKING_STYLE_DOTFILE);}#endif/* ** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the ** f_fstypename entry in the statfs structure as returned by stat() for ** the file system hosting the database file and selects  the appropriate** locking style based on its value.  These values and assignments are ** based on Darwin/OSX behavior and have not been thoroughly tested on ** other systems.**** If SQLITE_ENABLE_LOCKING_STYLE is not defined, this function always** returns LOCKING_STYLE_POSIX.*/#if SQLITE_ENABLE_LOCKING_STYLEstatic int detectLockingStyle(  sqlite3_vfs *pVfs,  const char *filePath,   int fd){#if IS_VXWORKS  if( !filePath ){    return LOCKING_STYLE_NONE;  }  if( pVfs->pAppData ){    return SQLITE_PTR_TO_INT(pVfs->pAppData);  }  if (access(filePath, 0) != -1){    return testLockingStyle(fd);  }#else  struct Mapping {    const char *zFilesystem;    int eLockingStyle;  } aMap[] = {    { "hfs",    LOCKING_STYLE_POSIX },    { "ufs",    LOCKING_STYLE_POSIX },    { "afpfs",  LOCKING_STYLE_AFP },#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB    { "smbfs",  LOCKING_STYLE_AFP },#else    { "smbfs",  LOCKING_STYLE_FLOCK },#endif    { "msdos",  LOCKING_STYLE_DOTFILE },    { "webdav", LOCKING_STYLE_NONE },    { 0, 0 }  };  int i;  struct statfs fsInfo;  if( !filePath ){    return LOCKING_STYLE_NONE;  }  if( pVfs->pAppData ){    return SQLITE_PTR_TO_INT(pVfs->pAppData);  }  if( statfs(filePath, &fsInfo) != -1 ){    if( fsInfo.f_flags & MNT_RDONLY ){      return LOCKING_STYLE_NONE;    }    for(i=0; aMap[i].zFilesystem; i++){      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){        return aMap[i].eLockingStyle;      }    }  }  /* Default case. Handles, amongst others, "nfs". */  return testLockingStyle(fd);  #endif /* if IS_VXWORKS */  return LOCKING_STYLE_POSIX;}#else  #define detectLockingStyle(x,y,z) LOCKING_STYLE_POSIX#endif /* ifdef SQLITE_ENABLE_LOCKING_STYLE *//*** Given a file descriptor, locate lockInfo and openCnt structures that** describes that file descriptor.  Create new ones if necessary.  The** return values might be uninitialized if an error occurs.**** Return an appropriate error code.*/static int findLockInfo(  int fd,                      /* The file descriptor used in the key */#if IS_VXWORKS  void *rnam,                  /* vxWorks realname */#endif

⌨️ 快捷键说明

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