DBD-SQLite-Amalgamation
view release on metacpan or search on metacpan
sqlite-amalgamation.c view on Meta::CPAN
214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429**
** Bummer. If you ask me, this is broken. Badly broken. It means
** competing threads of the same process. POSIX locks will work fine
** to synchronize access
for
threads in separate processes, but not
** threads within the same process.
**
** To work
around
the problem, SQLite
has
to manage file locks internally
** on its own. Whenever a new database is opened, we have to find the
** 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
sqlite-amalgamation.c view on Meta::CPAN
217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814
/* Testing
for
flock
() can give false positives. So
if
if
the above
** test fails, then we fall back to using dot-file style locking.
*/
return
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.
*/
static
int
detectLockingStyle(
sqlite3_vfs
*pVfs
,
sqlite-amalgamation.c view on Meta::CPAN
2186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906
int
fd, /* The file descriptor used in the key */
struct lockInfo *
*ppLock
, /* Return the lockInfo structure here */
struct openCnt *
*ppOpen
/* Return the openCnt structure here */
){
int
rc;
struct lockKey key1;
struct openKey key2;
struct
stat
statbuf;
struct lockInfo
*pLock
;
struct openCnt
*pOpen
;
rc = fstat(fd,
&statbuf
);
if
( rc!=0 ){
#ifdef EOVERFLOW
if
( errno==EOVERFLOW )
return
SQLITE_NOLFS;
#endif
return
SQLITE_IOERR;
}
/* On OS X on an msdos filesystem, the inode number is reported
** incorrectly
for
zero-size files. See ticket
#3260. To work
**
around
this problem (we consider it a bug in OS X, not SQLite)
** we always increase the file size to 1 by writing a single byte
** prior to accessing the inode number. The one byte written is
** an ASCII
'S'
character which also happens to be the first byte
** in the header of every SQLite database. In this way,
if
there
** is a race condition such that another thread
has
already populated
** the first page of the database,
no
damage is done.
*/
if
( statbuf.st_size==0 ){
write
(fd,
"S"
, 1);
rc = fstat(fd,
&statbuf
);
if
( rc!=0 ){
return
SQLITE_IOERR;
}
}
memset(
&key1
, 0, sizeof(key1));
key1.dev = statbuf.st_dev;
key1.ino = statbuf.st_ino;
#if SQLITE_THREADSAFE
if
( threadsOverrideEachOthersLocks<0 ){
sqlite-amalgamation.c view on Meta::CPAN
223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324
}
}
/*
** Determine the current size of a file in bytes
*/
static
int
unixFileSize(sqlite3_file
*id
, i64
*pSize
){
int
rc;
struct
stat
buf;
assert( id );
rc = fstat(((unixFile*)id)->h,
&buf
);
SimulateIOError( rc=1 );
if
( rc!=0 ){
return
SQLITE_IOERR_FSTAT;
}
*pSize
= buf.st_size;
/* When opening a zero-size database, the findLockInfo() procedure
** writes a single byte into that file in order to work
around
a bug
** in the OS-X msdos filesystem. In order to avoid problems
with
upper
** layers, we need to report this file size as zero even though it is
sqlite-amalgamation.c view on Meta::CPAN
231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158#pragma mark Old-School .lock file based locking
static
int
dotlockCheckReservedLock(sqlite3_file
*id
,
int
*pResOut
) {
int
r = 1;
unixFile
*pFile
= (unixFile*)id;
char
*zLockFile
= (char *)pFile->lockingContext;
if
(pFile->locktype != RESERVED_LOCK) {
struct
stat
statBuf;
if
(
lstat
(zLockFile,
&statBuf
) != 0){
/* file does not exist, we could have it
if
we want it */
r = 0;
}
}
*pResOut
= r;
return
SQLITE_OK;
}
static
int
dotlockLock(sqlite3_file
*id
,
int
locktype) {
sqlite-amalgamation.c view on Meta::CPAN
231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185if
(pFile->locktype > NO_LOCK) {
pFile->locktype = locktype;
/* Always update the timestamp on the old file */
utimes(zLockFile, NULL);
return
SQLITE_OK;
}
/* check to see
if
lock
file already
exists
*/
struct
stat
statBuf;
if
(
lstat
(zLockFile,
&statBuf
) == 0){
return
SQLITE_BUSY; /* it does, busy */
}
/* grab an exclusive
lock
*/
fd =
open
(zLockFile,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);
sqlite-amalgamation.c view on Meta::CPAN
234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError(
return
SQLITE_IOERR );
azDirs[0] = sqlite3_temp_directory;
for
(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
if
( azDirs[i]==0 )
continue
;
if
(
stat
(azDirs[i],
&buf
) )
continue
;
if
( !S_ISDIR(buf.st_mode) )
continue
;
if
( access(azDirs[i], 07) )
continue
;
zDir = azDirs[i];
break;
}
/* Check that the output buffer is large enough
for
the temporary file
** name. If it is not,
return
SQLITE_ERROR.
*/
if
( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
( run in 0.240 second using v1.01-cache-2.11-cpan-00829025b61 )