📄 os_unix.c
字号:
} } } if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) { if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)){ /* failed to release the pending lock */ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ } } if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) { if (_AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0)) { /* failed to release the reserved lock */ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ } } } if( locktype==NO_LOCK ){ int failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST + context->sharedLockByte, 1, 0); if (failed) { rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ } } if (rc == SQLITE_OK) pFile->locktype = locktype; leaveMutex(); return rc;}/*** Close a file & cleanup AFP specific locking context */static int afpUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; afpUnixUnlock(id, NO_LOCK); sqlite3_free(pFile->lockingContext); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK;}#pragma mark flock() style locking/*** The flockLockingContext is not used*/typedef void flockLockingContext;static int flockUnixCheckReservedLock(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; if (pFile->locktype == RESERVED_LOCK) { return 1; /* already have a reserved lock */ } else { /* attempt to get the lock */ int rc = flock(pFile->h, LOCK_EX | LOCK_NB); if (!rc) { /* got the lock, unlock it */ flock(pFile->h, LOCK_UN); return 0; /* no one has it reserved */ } return 1; /* someone else might have it reserved */ }}static int flockUnixLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ if (pFile->locktype > NO_LOCK) { pFile->locktype = locktype; return SQLITE_OK; } /* grab an exclusive lock */ int rc = flock(pFile->h, LOCK_EX | LOCK_NB); if (rc) { /* didn't get, must be busy */ return SQLITE_BUSY; } else { /* got it, set the type and return ok */ pFile->locktype = locktype; return SQLITE_OK; }}static int flockUnixUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; assert( locktype<=SHARED_LOCK ); /* no-op if possible */ if( pFile->locktype==locktype ){ return SQLITE_OK; } /* shared can just be set because we always have an exclusive */ if (locktype==SHARED_LOCK) { pFile->locktype = locktype; return SQLITE_OK; } /* no, really, unlock. */ int rc = flock(pFile->h, LOCK_UN); if (rc) return SQLITE_IOERR_UNLOCK; else { pFile->locktype = NO_LOCK; return SQLITE_OK; }}/*** Close a file.*/static int flockUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; flockUnixUnlock(id, NO_LOCK); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK;}#pragma mark Old-School .lock file based locking/*** The dotlockLockingContext structure contains all dotlock (.lock) lock** specific state*/typedef struct dotlockLockingContext dotlockLockingContext;struct dotlockLockingContext { char *lockPath;};static int dotlockUnixCheckReservedLock(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context; context = (dotlockLockingContext*)pFile->lockingContext; if (pFile->locktype == RESERVED_LOCK) { return 1; /* already have a reserved lock */ } else { struct stat statBuf; if (lstat(context->lockPath,&statBuf) == 0){ /* file exists, someone else has the lock */ return 1; }else{ /* file does not exist, we could have it if we want it */ return 0; } }}static int dotlockUnixLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context; int fd; context = (dotlockLockingContext*)pFile->lockingContext; /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ if (pFile->locktype > NO_LOCK) { pFile->locktype = locktype; /* Always update the timestamp on the old file */ utimes(context->lockPath,NULL); return SQLITE_OK; } /* check to see if lock file already exists */ struct stat statBuf; if (lstat(context->lockPath,&statBuf) == 0){ return SQLITE_BUSY; /* it does, busy */ } /* grab an exclusive lock */ fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600); if( fd<0 ){ /* failed to open/create the file, someone else may have stolen the lock */ return SQLITE_BUSY; } close(fd); /* got it, set the type and return ok */ pFile->locktype = locktype; return SQLITE_OK;}static int dotlockUnixUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context; context = (dotlockLockingContext*)pFile->lockingContext; assert( locktype<=SHARED_LOCK ); /* no-op if possible */ if( pFile->locktype==locktype ){ return SQLITE_OK; } /* shared can just be set because we always have an exclusive */ if (locktype==SHARED_LOCK) { pFile->locktype = locktype; return SQLITE_OK; } /* no, really, unlock. */ unlink(context->lockPath); pFile->locktype = NO_LOCK; return SQLITE_OK;}/* ** Close a file. */static int dotlockUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; dotlockUnixUnlock(id, NO_LOCK); sqlite3_free(pFile->lockingContext); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK;}#pragma mark No locking/*** The nolockLockingContext is void*/typedef void nolockLockingContext;static int nolockUnixCheckReservedLock(sqlite3_file *id) { return 0;}static int nolockUnixLock(sqlite3_file *id, int locktype) { return SQLITE_OK;}static int nolockUnixUnlock(sqlite3_file *id, int locktype) { return SQLITE_OK;}/*** Close a file.*/static int nolockUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if( !pFile ) return SQLITE_OK; if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK;}#endif /* SQLITE_ENABLE_LOCKING_STYLE *//*** Information and control of an open file handle.*/static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; } } return SQLITE_ERROR;}/*** 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 its journal file) that the sector size will be the** same for both.*/static int unixSectorSize(sqlite3_file *id){ return SQLITE_DEFAULT_SECTOR_SIZE;}/*** Return the device characteristics for the file. This is always 0.*/static int unixDeviceCharacteristics(sqlite3_file *id){ return 0;}/*** This vector defines all the methods that can operate on an sqlite3_file** for unix.*/static const sqlite3_io_methods sqlite3UnixIoMethod = { 1, /* iVersion */ unixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, unixLock, unixUnlock, unixCheckReservedLock, unixFileControl, unixSectorSize, unixDeviceCharacteristics};#ifdef SQLITE_ENABLE_LOCKING_STYLE/*** This vector defines all the methods that can operate on an sqlite3_file** for unix with AFP style file locking.*/static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = { 1, /* iVersion */ afpUnixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, afpUnixLock, afpUnixUnlock, afpUnixCheckReservedLock, unixFileControl, unixSectorSize, unixDeviceCharacteristics};/*** This vector defines all the methods that can operate on an sqlite3_file** for unix with flock() style file locking.*/static const sqlite3_io_methods sqlite3FlockLockingUnixIoMethod = { 1, /* iVersion */ flockUnixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, flockUnixLock, flockUnixUnlock, flockUnixCheckReservedLock, unixFileControl, unixSectorSize, unixDeviceCharacteristics};/*** This vector defines all the methods that can operate on an sqlite3_file** for unix with dotlock style file locking.*/static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = { 1, /* iVersion */ dotlockUnixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, dotlockUnixLock, dotlockUnixUnlock, dotlockUnixCheckReservedLock, unixFileControl, unixSectorSize, unixDeviceCharacteristics};/*** This vector defines all the methods that can operate on an sqlite3_file** for unix with nolock style file locking.*/static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = { 1, /* iVersion */ nolockUnixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, nolockUnixLock, nolockUnixUnlock, nolockUnixCheckReservedLock,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -