DBD-SQLite2
view release on metacpan or search on metacpan
136137138139140141142143144145146147148149150151152153154155156**
** 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 OsFile 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 OsFile structures
293294295296297298299300301302303304305306307308309310311312313
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 )
return
1;
memset(
&key1
, 0, sizeof(key1));
key1.dev = statbuf.st_dev;
key1.ino = statbuf.st_ino;
key1.pid = getpid();
memset(
&key2
, 0, sizeof(key2));
key2.dev = statbuf.st_dev;
key2.ino = statbuf.st_ino;
pLock = (struct lockInfo*)sqliteHashFind(
&lockHash
,
&key1
, sizeof(key1));
if
( pLock==0 ){
801802803804805806807808809810811812813814815816817818819820821static unsigned char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
;
int
i, j;
struct
stat
buf;
const char
*zDir
=
"."
;
azDirs[0] = sqlite_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;
}
do
{
sprintf
(zBuf,
"%s/"
TEMP_FILE_PREFIX, zDir);
j = strlen(zBuf);
sqliteRandomness(15,
&zBuf
[j]);
for
(i=0; i<15; i++, j++){
119511961197119811991200120112021203120412051206120712081209121012111212121312141215#endif
}
/*
** Determine the current size of a file in bytes
*/
int
sqliteOsFileSize(OsFile
*id
, sql_off_t
*pSize
){
#if OS_UNIX
struct
stat
buf;
SimulateIOError(SQLITE_IOERR);
if
( fstat(id->fd,
&buf
)!=0 ){
return
SQLITE_IOERR;
}
*pSize
= buf.st_size;
return
SQLITE_OK;
#endif
#if OS_WIN
DWORD upperBits, lowerBits;
SimulateIOError(SQLITE_IOERR);
lowerBits = GetFileSize(id->h,
&upperBits
);
*pSize
= (((sql_off_t)upperBits)<<32) + lowerBits;
( run in 0.219 second using v1.01-cache-2.11-cpan-ec4f86ec37b )