-C Implicit\sstring->numeric\sconversion\sshould\sgo\sto\san\sinteger\svalue\swhen\npossible.\s\sTicket\s#3257.\s(CVS\s5502)
-D 2008-07-30T13:27:11
+C In\sthe\sunix\sOS\simplementation,\sreplace\sinode\shash\stables\swith\slinked\slists.\s(CVS\s5503)
+D 2008-07-30T15:27:54
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in bbb62eecc851379aef5a48a1bf8787eb13e6ec06
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892
F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
F src/os_os2.c 676ed273b17bd260f905df81375c9f9950d85517
-F src/os_unix.c 1df6108efdb7957a9f28b9700600e58647c9c12d
+F src/os_unix.c c778a6b7098f54ee2e4420150265ad3d26824c96
F src/os_win.c 50ec783403b418ddc9e6e05d541c6027dfd41070
F src/pager.c a6ecad26297469a8a3d1fd7a7c3dc2d603955044
F src/pager.h 588c1ac195228b2da45c4e5f7ab6c2fd253d1751
F src/status.c ca61c18b6f1c632b771514e0c39a7d662c805bbf
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
F src/tclsqlite.c ec46084184f033ba396a9ee7b5514b695083d0f3
-F src/test1.c 346e9262793be825ebadd9e69600d1b4682650f1
+F src/test1.c c7d37c6d6ce5a84c45546dfafae12e5c46c656ce
F src/test2.c 7a634c1e044be3ea5845e65155fdd1cab13936cb
F src/test3.c e00795839be38f0345a4845170426fb17d828bf9
F src/test4.c 41056378671e7b00e6305fa9ac6fa27e6f96f406
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 4a6ee88697ddc28e0c7df1954d1526de18191827
-R 1fc491d5b31cb2a2cf0986670de436ee
+P da0e4bff30a77f72ae283406b547401c2ebb42c5
+R 4761a1459dbfe21d158c4e02d11ac727
U drh
-Z 6e72d4e65f10edd96172495856b81fe0
+Z 2fbbc6538919439da5b60f94f6787348
**
** This file contains code that is specific to Unix systems.
**
-** $Id: os_unix.c,v 1.193 2008/07/10 00:32:42 drh Exp $
+** $Id: os_unix.c,v 1.194 2008/07/30 15:27:54 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX /* This file is used on unix only */
int cnt; /* Number of SHARED locks held */
int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
int nRef; /* Number of pointers to this structure */
+ struct lockInfo *pNext, *pPrev; /* List of all lockInfo objects */
};
/*
int nLock; /* Number of outstanding locks */
int nPending; /* Number of pending close() operations */
int *aPending; /* Malloced space holding fd's awaiting a close() */
+ struct openCnt *pNext, *pPrev; /* List of all openCnt objects */
};
-/*
-** These hash tables map inodes and file descriptors (really, lockKey and
-** openKey structures) into lockInfo and openCnt structures. Access to
-** these hash tables must be protected by a mutex.
+/*
+** List of all lockInfo and openCnt objects. This used to be a hash
+** table. But the number of objects is rarely more than a dozen and
+** never exceeds a few thousand. And lookup is not on a critical
+** path oo a simple linked list will suffice.
*/
-static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
-static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
+static struct lockInfo *lockList = 0;
+static struct openCnt *openList = 0;
/*
** The locking styles are associated with the different file locking
** file systems that are known to be unsupported
*/
#define LOCKING_STYLE_POSIX 1
-#define LOCKING_STYLE_FLOCK 2
+#define LOCKING_STYLE_NONE 2
#define LOCKING_STYLE_DOTFILE 3
-#define LOCKING_STYLE_NONE 4
+#define LOCKING_STYLE_FLOCK 4
#define LOCKING_STYLE_AFP 5
/*
if( pLock ){
pLock->nRef--;
if( pLock->nRef==0 ){
- sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 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);
}
}
if( pOpen ){
pOpen->nRef--;
if( pOpen->nRef==0 ){
- sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
- free(pOpen->aPending);
+ 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);
}
}
memset(&key2, 0, sizeof(key2));
key2.dev = statbuf.st_dev;
key2.ino = statbuf.st_ino;
- pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
+ pLock = lockList;
+ while( pLock && memcmp(&key1, &pLock->key, sizeof(key1)) ){
+ pLock = pLock->pNext;
+ }
if( pLock==0 ){
- struct lockInfo *pOld;
pLock = sqlite3_malloc( sizeof(*pLock) );
if( pLock==0 ){
rc = SQLITE_NOMEM;
pLock->nRef = 1;
pLock->cnt = 0;
pLock->locktype = 0;
- pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
- if( pOld!=0 ){
- assert( pOld==pLock );
- sqlite3_free(pLock);
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
+ pLock->pNext = lockList;
+ pLock->pPrev = 0;
+ if( lockList ) lockList->pPrev = pLock;
+ lockList = pLock;
}else{
pLock->nRef++;
}
*ppLock = pLock;
if( ppOpen!=0 ){
- pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
+ pOpen = openList;
+ while( pOpen && memcmp(&key2, &pOpen->key, sizeof(key2)) ){
+ pOpen = pOpen->pNext;
+ }
if( pOpen==0 ){
- struct openCnt *pOld;
pOpen = sqlite3_malloc( sizeof(*pOpen) );
if( pOpen==0 ){
releaseLockInfo(pLock);
pOpen->nLock = 0;
pOpen->nPending = 0;
pOpen->aPending = 0;
- pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
- if( pOld!=0 ){
- assert( pOld==pOpen );
- sqlite3_free(pOpen);
- releaseLockInfo(pLock);
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
+ pOpen->pNext = openList;
+ pOpen->pPrev = 0;
+ if( openList ) openList->pPrev = pOpen;
+ openList = pOpen;
}else{
pOpen->nRef++;
}
for(i=0; i<pOpen->nPending; i++){
close(pOpen->aPending[i]);
}
- free(pOpen->aPending);
+ sqlite3_free(pOpen->aPending);
pOpen->nPending = 0;
pOpen->aPending = 0;
}
*/
int *aNew;
struct openCnt *pOpen = pFile->pOpen;
- aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+ aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
if( aNew==0 ){
/* If a malloc fails, just leak the file descriptor */
}else{
}
-#pragma mark No locking
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
** The nolockLockingContext is void
return closeUnixFile(id);
}
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
/*
** Information and control of an open file handle.
int h, /* Open file descriptor of file being opened */
int dirfd, /* Directory file descriptor */
sqlite3_file *pId, /* Write to the unixFile structure here */
- const char *zFilename /* Name of the file being opened */
+ const char *zFilename, /* Name of the file being opened */
+ int noLock /* Omit locking if true */
){
+ int eLockingStyle;
+ unixFile *pNew = (unixFile *)pId;
+ int rc = SQLITE_OK;
+
/* Macro to define the static contents of an sqlite3_io_methods
** structure for a unix backend file. Different locking methods
** require different functions for the xClose, xLock, xUnlock and
}
static sqlite3_io_methods aIoMethod[] = {
IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock)
+ ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
#ifdef SQLITE_ENABLE_LOCKING_STYLE
- ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
,IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock)
- ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
+ ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
,IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock)
#endif
};
-
- int eLockingStyle;
- unixFile *pNew = (unixFile *)pId;
- int rc = SQLITE_OK;
+ /* The order of the IOMETHODS macros above is important. It must be the
+ ** same order as the LOCKING_STYLE numbers
+ */
+ assert(LOCKING_STYLE_POSIX==1);
+ assert(LOCKING_STYLE_NONE==2);
+ assert(LOCKING_STYLE_DOTFILE==3);
+ assert(LOCKING_STYLE_FLOCK==4);
+ assert(LOCKING_STYLE_AFP==5);
assert( pNew->pLock==NULL );
assert( pNew->pOpen==NULL );
pNew->dirfd = dirfd;
SET_THREADID(pNew);
- assert(LOCKING_STYLE_POSIX==1);
- assert(LOCKING_STYLE_FLOCK==2);
- assert(LOCKING_STYLE_DOTFILE==3);
- assert(LOCKING_STYLE_NONE==4);
- assert(LOCKING_STYLE_AFP==5);
- eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+ if( noLock ){
+ eLockingStyle = LOCKING_STYLE_NONE;
+ }else{
+ eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+ }
switch( eLockingStyle ){
int dirfd = -1; /* Directory file descriptor */
int oflags = 0; /* Flags to pass to open() */
int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int noLock; /* True to omit locking primitives */
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif
- return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath);
+ noLock = eType!=SQLITE_OPEN_MAIN_DB;
+ return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock);
}
/*
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.315 2008/07/12 14:52:20 drh Exp $
+** $Id: test1.c,v 1.316 2008/07/30 15:27:54 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
return TCL_OK;
}
-#ifndef SQLITE_OMIT_DISKIO
-#if 0
-/*
-** Usage: sqlite3OsOpenReadWrite <filename>
-*/
-static int test_sqlite3OsOpenReadWrite(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3_file *pFile;
- int rc;
- int dummy;
- char zBuf[100];
-
- if( objc!=2 ){
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tcl_GetString(objv[0]), " filename", 0);
- return TCL_ERROR;
- }
-
- rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy);
- if( rc!=SQLITE_OK ){
- Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
- return TCL_ERROR;
- }
- sqlite3TestMakePointerStr(interp, zBuf, pFile);
- Tcl_SetResult(interp, zBuf, 0);
- return TCL_ERROR;
-}
-
-/*
-** Usage: sqlite3OsClose <file handle>
-*/
-static int test_sqlite3OsClose(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3_file *pFile;
- int rc;
-
- if( objc!=2 ){
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tcl_GetString(objv[0]), " filehandle", 0);
- return TCL_ERROR;
- }
-
- if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
- return TCL_ERROR;
- }
- rc = sqlite3OsClose(&pFile);
- if( rc!=SQLITE_OK ){
- Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3OsLock <file handle> <locktype>
-*/
-static int test_sqlite3OsLock(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3_file * pFile;
- int rc;
-
- if( objc!=3 ){
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tcl_GetString(objv[0]),
- " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
- return TCL_ERROR;
- }
-
- if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
- return TCL_ERROR;
- }
-
- if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){
- rc = sqlite3OsLock(pFile, SHARED_LOCK);
- }
- else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){
- rc = sqlite3OsLock(pFile, RESERVED_LOCK);
- }
- else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){
- rc = sqlite3OsLock(pFile, PENDING_LOCK);
- }
- else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){
- rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK);
- }else{
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tcl_GetString(objv[0]),
- " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
- return TCL_ERROR;
- }
-
- if( rc!=SQLITE_OK ){
- Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3OsUnlock <file handle>
-*/
-static int test_sqlite3OsUnlock(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- sqlite3_file * pFile;
- int rc;
-
- if( objc!=2 ){
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tcl_GetString(objv[0]), " filehandle", 0);
- return TCL_ERROR;
- }
-
- if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
- return TCL_ERROR;
- }
- rc = sqlite3OsUnlock(pFile, NO_LOCK);
- if( rc!=SQLITE_OK ){
- Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
-** Usage: sqlite3OsTempFileName
-*/
-static int test_sqlite3OsTempFileName(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- char zFile[SQLITE_TEMPNAME_SIZE];
- int rc;
-
- rc = sqlite3OsTempFileName(zFile);
- if( rc!=SQLITE_OK ){
- Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
- return TCL_ERROR;
- }
- Tcl_AppendResult(interp, zFile, 0);
- return TCL_OK;
-}
-#endif
-#endif
-
/*
** Usage: sqlite_set_magic DB MAGIC-NUMBER
**
{ "sqlite3_vfs_list", vfs_list, 0 },
/* Functions from os.h */
-#ifndef SQLITE_OMIT_DISKIO
-#if 0
- { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
- { "sqlite3OsClose", test_sqlite3OsClose, 0 },
- { "sqlite3OsLock", test_sqlite3OsLock, 0 },
- { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 },
-
- /* Custom test interfaces */
- { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 },
-#endif
-#endif
#ifndef SQLITE_OMIT_UTF16
{ "add_test_collate", test_collate, 0 },
{ "add_test_collate_needed", test_collate_needed, 0 },