Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the locking-style code in os_unix.c. The updates are as yet untested. (CVS 4244) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
41f2175b1ed7eccf271b687ee5c3ea26 |
User & Date: | danielk1977 2007-08-20 06:44:22.000 |
Context
2007-08-20
| ||
11:12 | Get main.c to compile when HAVE_USLEEP is 0. (CVS 4245) (check-in: b27f022fb9 user: drh tags: trunk) | |
06:44 | Update the locking-style code in os_unix.c. The updates are as yet untested. (CVS 4244) (check-in: 41f2175b1e user: danielk1977 tags: trunk) | |
05:36 | Fix full_fsync() related functionality broken as part of the migration to sqlite3_vfs. (CVS 4243) (check-in: cb24cda179 user: danielk1977 tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
77 78 79 80 81 82 83 | /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 /* | | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | /* ** Maximum supported path-length. */ #define MAX_PATHNAME 512 /* ** The unixFile structure is subclass of sqlite3_file specific for the unix ** protability layer. */ typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ struct openCnt *pOpen; /* Info about all open fd's on this inode */ struct lockInfo *pLock; /* Info about locks on this inode */ #ifdef SQLITE_ENABLE_LOCKING_STYLE void *lockingContext; /* Locking style specific state */ #endif /* SQLITE_ENABLE_LOCKING_STYLE */ int h; /* The file descriptor */ unsigned char locktype; /* The type of lock held on this fd */ unsigned char isOpen; /* True if needs to be closed */ int dirfd; /* File descriptor for the directory */ i64 offset; /* Seek offset */ #ifdef SQLITE_UNIX_THREADS pthread_t tid; /* The thread that "owns" this unixFile */ #endif }; /* ** Provide the ability to override some OS-layer functions during ** testing. This is used to simulate OS crashes to verify that |
︙ | ︙ | |||
129 130 131 132 133 134 135 | /* ** Do not include any of the File I/O interface procedures if the ** SQLITE_OMIT_DISKIO macro is defined (indicating that the database ** will be in-memory only) */ #ifndef SQLITE_OMIT_DISKIO | < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* ** Do not include any of the File I/O interface procedures if the ** SQLITE_OMIT_DISKIO macro is defined (indicating that the database ** will be in-memory only) */ #ifndef SQLITE_OMIT_DISKIO /* ** Define various macros that are missing from some systems. */ #ifndef O_LARGEFILE # define O_LARGEFILE 0 #endif |
︙ | ︙ | |||
169 170 171 172 173 174 175 | #ifdef SQLITE_UNIX_THREADS #define threadid pthread_self() #else #define threadid 0 #endif /* | | | | | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | #ifdef SQLITE_UNIX_THREADS #define threadid pthread_self() #else #define threadid 0 #endif /* ** Set or check the unixFile.tid field. This field is set when an unixFile ** is first opened. All subsequent uses of the unixFile verify that the ** same thread is operating on the unixFile. Some operating systems do ** not allow locks to be overridden by other threads and that restriction ** means that sqlite3* database handles cannot be moved from one thread ** to another. This logic makes sure a user does not try to do that ** by mistake. ** ** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to ** another as long as we are running on a system that supports threads ** overriding each others locks (which now the most common behavior) ** or if no locks are held. But the unixFile.pLock field needs to be ** recomputed because its key includes the thread-id. See the ** transferOwnership() function below for additional information */ #if defined(SQLITE_UNIX_THREADS) # define SET_THREADID(X) (X)->tid = pthread_self() # define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \ !pthread_equal((X)->tid, pthread_self())) |
︙ | ︙ | |||
228 229 230 231 232 233 234 | ** specific inode of the database file (the inode is determined by the ** st_dev and st_ino fields of the stat structure that fstat() fills in) ** and check for locks already existing on that inode. When locks are ** created or removed, we have to look at our own internal record of the ** locks to see if another thread has previously set a lock on that same ** inode. ** | | | | | | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | ** specific inode of the database file (the inode is determined by the ** st_dev and st_ino fields of the stat structure that fstat() fills in) ** and check for locks already existing on that inode. When locks are ** created or removed, we have to look at our own internal record of the ** locks to see if another thread has previously set a lock on that same ** inode. ** ** The sqlite3_file structure for POSIX is no longer just an integer file ** descriptor. It is now a structure that holds the integer file ** descriptor and a pointer to a structure that describes the internal ** locks on the corresponding inode. There is one locking structure ** per inode, so if the same inode is opened twice, both unixFile structures ** 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. ** ** 2004-Jan-11: ** More recent discoveries about POSIX advisory locks. (The more ** I discover, the more I realize the a POSIX advisory locks are ** an abomination.) ** ** If you close a file descriptor that points to a file that has locks, ** all locks on that file that are owned by the current process are ** released. To work around this problem, each unixFile structure contains ** a pointer to an openCnt structure. There is one openCnt structure ** per open inode, which means that multiple unixFile can point to a single ** openCnt. When an attempt is made to close an unixFile, if there are ** other unixFile open on the same inode that are holding locks, the call ** to close() the file descriptor is deferred until all of the locks clear. ** The openCnt structure keeps a list of file descriptors that need to ** be closed and that list is walked (and cleared) when the last lock ** clears. ** ** First, under Linux threads, because each thread has a separate ** process ID, lock operations in one thread do not override locks |
︙ | ︙ | |||
315 316 317 318 319 320 321 | }; /* ** An instance of the following structure is allocated for each open ** inode on each thread with a different process ID. (Threads have ** different process IDs on linux, but not on most other unixes.) ** | | | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | }; /* ** An instance of the following structure is allocated for each open ** inode on each thread with a different process ID. (Threads have ** different process IDs on linux, but not on most other unixes.) ** ** A single inode can have multiple file descriptors, so each unixFile ** structure contains a pointer to an instance of this object and this ** object keeps a count of the number of unixFile pointing to it. */ struct lockInfo { struct lockKey key; /* The lookup key */ int cnt; /* Number of SHARED locks held */ int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ int nRef; /* Number of pointers to this structure */ }; |
︙ | ︙ | |||
385 386 387 388 389 390 391 392 393 394 395 396 397 398 | flockLockingStyle, /* use flock() */ dotlockLockingStyle, /* use <file>.lock files */ noLockingStyle, /* useful for read-only file system */ unsupportedLockingStyle /* indicates unsupported file system */ } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ static void enterMutex(){ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } static void leaveMutex(){ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } | > > > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | flockLockingStyle, /* use flock() */ dotlockLockingStyle, /* use <file>.lock files */ noLockingStyle, /* useful for read-only file system */ unsupportedLockingStyle /* indicates unsupported file system */ } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Helper functions to obtain and relinquish the global mutex. */ static void enterMutex(){ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } static void leaveMutex(){ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } |
︙ | ︙ | |||
563 564 565 566 567 568 569 | } #ifdef 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. */ | | > | > | | > | > | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | } #ifdef 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. */ static sqlite3LockingStyle sqlite3TestLockingStyle( const char *filePath, int fd ){ /* test byte-range lock using fcntl */ struct flock lockInfo; 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 posixLockingStyle; } /* testing for flock can give false positives. So if if the above test ** fails, then we fall back to using dot-lock style locking. */ return dotlockLockingStyle; } /* ** Examines the f_fstypename entry in the statfs structure as returned by ** stat() for the file system hosting the database file, assigns the ** appropriate locking style based on it's value. These values and ** assignments are based on Darwin/OSX behavior and have not been tested on ** other systems. */ static sqlite3LockingStyle sqlite3DetectLockingStyle( const char *filePath, int fd ){ #ifdef SQLITE_FIXED_LOCKING_STYLE return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE; #else struct statfs fsInfo; if (statfs(filePath, &fsInfo) == -1) |
︙ | ︙ | |||
786 787 788 789 790 791 792 | } } #else /* On single-threaded builds, ownership transfer is a no-op */ # define transferOwnership(X) SQLITE_OK #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 792 793 794 795 796 797 798 799 800 801 802 803 804 805 | } } #else /* On single-threaded builds, ownership transfer is a no-op */ # define transferOwnership(X) SQLITE_OK #endif /* ** Seek to the offset in id->offset then read cnt bytes into pBuf. ** Return the number of bytes actually read. Update the offset. */ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ int got; i64 newOffset; |
︙ | ︙ | |||
1210 1211 1212 1213 1214 1215 1216 | #endif close(pFile->dirfd); /* Only need to sync once, so close the directory */ pFile->dirfd = -1; /* when we are done. */ } return SQLITE_OK; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | #endif close(pFile->dirfd); /* Only need to sync once, so close the directory */ pFile->dirfd = -1; /* when we are done. */ } return SQLITE_OK; } /* ** Truncate an open file to a specified size */ static int unixTruncate(sqlite3_file *id, i64 nByte){ int rc; assert( id ); rc = ftruncate(((unixFile*)id)->h, (off_t)nByte); |
︙ | ︙ | |||
1384 1385 1386 1387 1388 1389 1390 | assert( pFile ); OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), locktypeName(pLock->locktype), pLock->cnt , getpid()); /* If there is already a lock of this type or more restrictive on the | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 | assert( pFile ); OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), locktypeName(pLock->locktype), pLock->cnt , getpid()); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the end_lock: exit path, as ** enterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h, locktypeName(locktype)); return SQLITE_OK; } |
︙ | ︙ | |||
1412 1413 1414 1415 1416 1417 1418 | rc = transferOwnership(pFile); if( rc!=SQLITE_OK ){ leaveMutex(); return rc; } pLock = pFile->pLock; | | | 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | rc = transferOwnership(pFile); if( rc!=SQLITE_OK ){ leaveMutex(); return rc; } pLock = pFile->pLock; /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ if( (pFile->locktype!=pLock->locktype && (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) ){ rc = SQLITE_BUSY; goto end_lock; |
︙ | ︙ | |||
1685 1686 1687 1688 1689 1690 1691 | unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ int fd; /* file desc to assoc this lock with */ }; #define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) | > | | | | > | > > > | < > > | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 | unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ int fd; /* file desc to assoc this lock with */ }; #define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) /* ** Return 0 on success, 1 on failure. To match the behavior of the ** normal posix file locking (used in unixLock for example), we should ** provide 'richer' return codes - specifically to differentiate between ** 'file busy' and 'file system error' results. */ static int _AFPFSSetLock( const char *path, int fd, unsigned long long offset, unsigned long long length, int setLockFlag ){ struct ByteRangeLockPB2 pb; int err; pb.unLockFlag = setLockFlag ? 0 : 1; pb.startEndFlag = 0; pb.offset = offset; pb.length = length; |
︙ | ︙ | |||
1718 1719 1720 1721 1722 1723 1724 | /* ** 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. If the file is unlocked or holds only SHARED locks, then ** return zero. */ | | | 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 | /* ** 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. If the file is unlocked or holds only SHARED locks, then ** return zero. */ static int afpUnixCheckReservedLock(sqlite3_file *id){ int r = 0; unixFile *pFile = (unixFile*)id; assert( pFile ); afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; /* Check if a thread in this process holds such a lock */ |
︙ | ︙ | |||
1751 1752 1753 1754 1755 1756 1757 | OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); return r; } /* AFP-style locking following the behavior of unixLock, see the unixLock ** function comments for details of lock management. */ | | | | 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 | OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); return r; } /* AFP-style locking following the behavior of unixLock, see the unixLock ** function comments for details of lock management. */ static int afpUnixLock(sqlite3_file *id, int locktype) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; int gotPendingLock = 0; assert( pFile ); OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), getpid()); /* If there is already a lock of this type or more restrictive on the ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as ** enterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h, locktypeName(locktype)); return SQLITE_OK; } |
︙ | ︙ | |||
1885 1886 1887 1888 1889 1890 1891 | /* ** Lower the locking level on file descriptor pFile 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. */ | | | 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 | /* ** Lower the locking level on file descriptor pFile 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. */ static int afpUnixUnlock(sqlite3_file *id, int locktype) { struct flock lock; int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; assert( pFile ); OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype, |
︙ | ︙ | |||
1953 1954 1955 1956 1957 1958 1959 | leaveMutex(); return rc; } /* ** Close a file & cleanup AFP specific locking context */ | | | | | | | | | | | | | | | < < | | | 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | leaveMutex(); return rc; } /* ** Close a file & cleanup AFP specific locking context */ static int afpUnixClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)pId; if( !pFile ) return SQLITE_OK; afpUnixUnlock(*pId, NO_LOCK); /* free the AFP locking structure */ if (pFile->lockingContext != NULL) { if (((afpLockingContext *)pFile->lockingContext)->filePath != NULL) sqlite3_free(((afpLockingContext*)pFile->lockingContext)->filePath); sqlite3_free(pFile->lockingContext); } if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; close(pFile->h); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); 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; |
︙ | ︙ | |||
2023 2024 2025 2026 2027 2028 2029 | } else { /* got it, set the type and return ok */ pFile->locktype = locktype; return SQLITE_OK; } } | | | 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 | } 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; |
︙ | ︙ | |||
2052 2053 2054 2055 2056 2057 2058 | return SQLITE_OK; } } /* ** Close a file. */ | | | | | | | | | < < | | | 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 | return SQLITE_OK; } } /* ** Close a file. */ static int flockUnixClose(sqlite3_file *pId) { unixFile *pFile = (unixFile*)*pId; if( !pFile ) return SQLITE_OK; flockUnixUnlock(*pId, NO_LOCK); if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); 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 = (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 = (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) { |
︙ | ︙ | |||
2136 2137 2138 2139 2140 2141 2142 | close(fd); /* got it, set the type and return ok */ pFile->locktype = locktype; return SQLITE_OK; } | | | 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 | 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 = (dotlockLockingContext *) pFile->lockingContext; assert( locktype<=SHARED_LOCK ); /* no-op if possible */ |
︙ | ︙ | |||
2163 2164 2165 2166 2167 2168 2169 | pFile->locktype = NO_LOCK; return SQLITE_OK; } /* ** Close a file. */ | | | | | | | | | | | | | < < | | | | | | | | | | | < < | | | | > | > | | < < | 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 | 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(*pId, NO_LOCK); /* free the dotlock locking structure */ if (pFile->lockingContext != NULL) { if (((dotlockLockingContext *)pFile->lockingContext)->lockPath != NULL) sqlite3_free( ( (dotlockLockingContext *) pFile->lockingContext)->lockPath); sqlite3_free(pFile->lockingContext); } if( pFile->dirfd>=0 ) close(pFile->dirfd); pFile->dirfd = -1; enterMutex(); close(pFile->h); leaveMutex(); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); 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(); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); return SQLITE_OK; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** TODO: xBreakLock() for this vfs. */ static int unixBreakLock(sqlite3_file *id){ assert(!"TODO: unixBreakLock()"); return 0; } /* ** Return an integer that indices the type of lock currently held ** by this handle. (Used for testing and analysis only.) */ static int unixLockState(sqlite3_file *id){ return ((unixFile*)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. |
︙ | ︙ | |||
2273 2274 2275 2276 2277 2278 2279 | /* ** Return the device characteristics for the file. This is always 0. */ static int unixDeviceCharacteristics(sqlite3_file *id){ return 0; } | < < < < < < < < < < < < < | | 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 | /* ** 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, |
︙ | ︙ | |||
2309 2310 2311 2312 2313 2314 2315 | unixLockState, unixSectorSize, unixDeviceCharacteristics }; #ifdef SQLITE_ENABLE_LOCKING_STYLE /* | | | | | > | < | | < | | < < | | | < | > > | > | | | | > | < | | < | | < < | | | < | > > | > | | | | > | < | | < | | < < | | | < | > > | > | | | | > < < < < < > > > | | | | | | > | < | < | | | | < < < | | | | | < < | 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 | unixLockState, 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 */ unixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, afpUnixLock, afpUnixUnlock, afpUnixCheckReservedLock, unixBreakLock, unixLockState, 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, unixBreakLock, unixLockState, 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, unixBreakLock, unixLockState, 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 sqlite3NolockLockingUnixIoMethod = { 1, /* iVersion */ nolockUnixClose, unixRead, unixWrite, unixTruncate, unixSync, unixFileSize, nolockUnixLock, nolockUnixUnlock, nolockUnixCheckReservedLock, unixBreakLock, unixLockState, unixSectorSize, unixDeviceCharacteristics }; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Allocate memory for a new unixFile and initialize that unixFile. ** Write a pointer to the new unixFile into *pId. ** If we run out of memory, close the file and return an error. */ #ifdef SQLITE_ENABLE_LOCKING_STYLE /* ** When locking extensions are enabled, the filepath and locking style ** are needed to determine the unixFile pMethod to use for locking operations. ** The locking-style specific lockingContext data structure is created ** and assigned here also. */ static int fillInUnixFile( int h, /* Open file descriptor of file being opened */ int dirfd, /* Directory file descriptor */ sqlite3_file *pId, /* Write completed initialization here */ const char *zFilename, /* Name of the file being opened */ ){ sqlite3LockingStyle lockingStyle; unixFile *pNew = (unixFile *)pId; int rc; memset(pNew, 0, sizeof(unixFile)); lockingStyle = sqlite3DetectLockingStyle(zFilename, h); if ( lockingStyle == posixLockingStyle ) { enterMutex(); rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); leaveMutex(); if( rc ){ close(h); unlink(zFilename); return SQLITE_NOMEM; } } else { /* pLock and pOpen are only used for posix advisory locking */ pNew->pLock = NULL; pNew->pOpen = NULL; } pNew->dirfd = -1; pNew->h = h; SET_THREADID(pNew); pNew = sqlite3_malloc( sizeof(unixFile) ); if( pNew==0 ){ close(h); enterMutex(); releaseLockInfo(pNew->pLock); releaseOpenCnt(pNew->pOpen); leaveMutex(); return SQLITE_NOMEM; }else{ switch(lockingStyle) { case afpLockingStyle: { /* afp locking uses the file path so it needs to be included in ** the afpLockingContext */ int nFilename; pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; pNew->lockingContext = |
︙ | ︙ | |||
2498 2499 2500 2501 2502 2503 2504 | pNew->pMethod = &sqlite3UnixIoMethod; break; case noLockingStyle: case unsupportedLockingStyle: default: pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; } | < | 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 | pNew->pMethod = &sqlite3UnixIoMethod; break; case noLockingStyle: case unsupportedLockingStyle: default: pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; } OpenCounter(+1); return SQLITE_OK; } } #else /* SQLITE_ENABLE_LOCKING_STYLE */ static int fillInUnixFile( int h, /* Open file descriptor on file being opened */ |
︙ | ︙ | |||
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 | #endif /* SQLITE_OMIT_DISKIO */ /*************************************************************************** ** Everything above deals with file I/O. Everything that follows deals ** with other miscellanous aspects of the operating system interface ****************************************************************************/ static int openDirectory(const char *zFilename, int *pFd){ char *zDirname; int ii; int fd; zDirname = (char *)sqlite3_malloc(MAX_PATHNAME); if( !zDirname ){ | > > > > > > > > > > | 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 | #endif /* SQLITE_OMIT_DISKIO */ /*************************************************************************** ** Everything above deals with file I/O. Everything that follows deals ** with other miscellanous aspects of the operating system interface ****************************************************************************/ /* ** Open a file descriptor to the directory containing file zFilename. ** If successful, *pFd is set to the opened file descriptor and ** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM ** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined ** value. ** ** If SQLITE_OK is returned, the caller is responsible for closing ** the file descriptor *pFd using close(). */ static int openDirectory(const char *zFilename, int *pFd){ char *zDirname; int ii; int fd; zDirname = (char *)sqlite3_malloc(MAX_PATHNAME); if( !zDirname ){ |
︙ | ︙ | |||
2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 | } sqlite3_free(zDirname); *pFd = fd; return (fd>0?SQLITE_OK:SQLITE_CANTOPEN); } /* ** Previously, the SQLite OS layer used three functions in place of this ** one: ** ** sqlite3OsOpenReadWrite(); ** sqlite3OsOpenReadOnly(); ** sqlite3OsOpenExclusive(); ** | > > | 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 | } sqlite3_free(zDirname); *pFd = fd; return (fd>0?SQLITE_OK:SQLITE_CANTOPEN); } /* ** Open the file zPath. ** ** Previously, the SQLite OS layer used three functions in place of this ** one: ** ** sqlite3OsOpenReadWrite(); ** sqlite3OsOpenReadOnly(); ** sqlite3OsOpenExclusive(); ** |
︙ | ︙ |