コード例 #1
0
        private static PgHdr pcache1Alloc(int nByte)
        {
            PgHdr p = null;

            Debug.Assert(MutexEx.NotHeld(pcache1.grp.mutex));
            StatusEx.sqlite3StatusSet(StatusEx.STATUS.PAGECACHE_SIZE, nByte);
            if (nByte <= pcache1.szSlot)
            {
                MutexEx.Enter(pcache1.mutex);
                p = pcache1.pFree._PgHdr;
                if (p != null)
                {
                    pcache1.pFree = pcache1.pFree.pNext;
                    pcache1.nFreeSlot--;
                    pcache1.bUnderPressure = pcache1.nFreeSlot < pcache1.nReserve;
                    Debug.Assert(pcache1.nFreeSlot >= 0);
                    StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_USED, 1);
                }
                MutexEx.Leave(pcache1.mutex);
            }
            if (p == null)
            {
                // Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get it from sqlite3Malloc instead.
                p = new PgHdr();
                {
                    var sz = nByte;
                    MutexEx.Enter(pcache1.mutex);
                    StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_OVERFLOW, sz);
                    MutexEx.Leave(pcache1.mutex);
                }
                SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.PCACHE);
            }
            return(p);
        }
コード例 #2
0
 private static void pcache1Free(ref PgHdr p)
 {
     if (p == null)
     {
         return;
     }
     if (p.CacheAllocated)
     {
         var pSlot = new PgFreeslot();
         MutexEx.Enter(pcache1.mutex);
         StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_USED, -1);
         pSlot._PgHdr  = p;
         pSlot.pNext   = pcache1.pFree;
         pcache1.pFree = pSlot;
         pcache1.nFreeSlot++;
         pcache1.bUnderPressure = pcache1.nFreeSlot < pcache1.nReserve;
         Debug.Assert(pcache1.nFreeSlot <= pcache1.nSlot);
         MutexEx.Leave(pcache1.mutex);
     }
     else
     {
         Debug.Assert(SysEx.sqlite3MemdebugHasType(p, SysEx.MEMTYPE.PCACHE));
         SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.HEAP);
         var iSize = MallocEx.sqlite3MallocSize(p.Data);
         MutexEx.Enter(pcache1.mutex);
         StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_OVERFLOW, -iSize);
         MutexEx.Leave(pcache1.mutex);
         MallocEx.sqlite3_free(ref p.Data);
     }
 }
コード例 #3
0
        public static VirtualFileSystem FindVfs(string zVfs)
        {
            VirtualFileSystem pVfs = null;

            //#if !SQLITE_OMIT_AUTOINIT
            //            var rc = sqlite3_initialize();
            //            if (rc != SQLITE.OK)
            //                return null;
            //#endif
#if SQLITE_THREADSAFE
            var mutex = MutexEx.Alloc(MutexEx.MUTEX.STATIC_MASTER);
#endif
            MutexEx.Enter(mutex);
            for (pVfs = vfsList; pVfs != null; pVfs = pVfs.pNext)
            {
                if (zVfs == null || zVfs == "")
                {
                    break;
                }
                if (zVfs == pVfs.zName)
                {
                    break;
                }
            }
            MutexEx.Leave(mutex);
            return(pVfs);
        }
コード例 #4
0
        static int OsLocaltime(time_t t, tm tm_)
        {
            int rc;
            MutexEx mutex = MutexEx.Alloc(MutexEx.MUTEX.STATIC_MASTER);
            MutexEx.Enter(mutex);
            tm x = localtime(t);
#if !OMIT_BUILTIN_TEST
            if (_localtimeFault) x = null;
#endif
            if (x != null) tm_ = x;
            MutexEx.Leave(mutex);
            rc = (x == null ? 1 : 0);
            return rc;
        }
コード例 #5
0
        public static void MakeRandomness(int count, ref long pBuf)
        {
            var buffer = new byte[count];

            pBuf = 0;
#if SQLITE_THREADSAFE
            var mutex = MutexEx.Alloc(MutexEx.MUTEX.STATIC_PRNG);
#endif
            MutexEx.Enter(mutex);
            while (count-- > 0)
            {
                pBuf = (uint)((pBuf << 8) + (byte)_r.Next(byte.MaxValue));
            }
            MutexEx.Leave(mutex);
        }
コード例 #6
0
        public static void MakeRandomness(byte[] buffer, int Offset, int count)
        {
            var iBuf = DateTime.Now.Ticks;

#if SQLITE_THREADSAFE
            var mutex = MutexEx.Alloc(MutexEx.MUTEX.STATIC_PRNG);
#endif
            MutexEx.Enter(mutex);
            while (count-- > 0)
            {
                iBuf             = (uint)((iBuf << 8) + (byte)_r.Next(byte.MaxValue));
                buffer[Offset++] = (byte)iBuf;
            }
            MutexEx.Leave(mutex);
        }
コード例 #7
0
        static void CurrentTimeFunc(FuncContext fctx, int argc, Mem[] argv)
        {
            string format = (string)sqlite3_user_data(fctx);
            Context ctx = sqlite3_context_db_handle(fctx);
            long iT;
            ctx.Vfs.CurrentTimeInt64(ref iT);
            time_t t = iT / 1000 - 10000 * (long)21086676;
            MutexEx mutex = MutexEx.Alloc(MutexEx.MUTEX.STATIC_MASTER);
            MutexEx.Enter(mutex);
            char zdtBuf;
            tm pTm;
            //pTm = gmtime(&t);
            //strftime(zdtBuf, 20, zFormat, pTm);
            MutexEx.Leave(mutex);

            sqlite3_result_text(fctx, zdtBuf, -1, SQLITE_TRANSIENT);
        }
コード例 #8
0
        internal bool removeFromSharingList()
        {
#if !SQLITE_OMIT_SHARED_CACHE
            MutexEx  pMaster;
            BtShared list;
            bool     removed = false;
            Debug.Assert(MutexEx.NotHeld(Mutex));
            pMaster = MutexEx.Alloc(MUTEX.STATIC_MASTER);
            MutexEx.Enter(pMaster);
            nRef--;
            if (nRef <= 0)
            {
                if (SysEx.getGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList) == this)
                {
                    SysEx.setGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList, Next);
                }
                else
                {
                    list = SysEx.getGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList);
                    while (Check.ALWAYS(list) != null && list.Next != this)
                    {
                        list = list.Next;
                    }
                    if (Check.ALWAYS(list) != null)
                    {
                        list.Next = Next;
                    }
                }
                if (MutexEx.SQLITE_THREADSAFE)
                {
                    MutexEx.Free(Mutex);
                }
                removed = true;
            }
            MutexEx.Leave(pMaster);
            return(removed);
#else
            return(true);
#endif
        }
コード例 #9
0
ファイル: Btree+Public.cs プロジェクト: smorey2/gpustructs
        // was:sqlite3BtreeOpen
        public static RC Open(VirtualFileSystem pVfs, string zFilename, sqlite3 db, ref Btree rTree, OPEN flags, VFSOPEN vfsFlags)
        {
            Btree p;                      // Handle to return   
            var rc = RC.OK;
            byte nReserve;                   // Byte of unused space on each page
            var zDbHeader = new byte[100]; // Database header content
            // True if opening an ephemeral, temporary database */
            bool isTempDb = string.IsNullOrEmpty(zFilename);
            // Set the variable isMemdb to true for an in-memory database, or  false for a file-based database.
#if SQLITE_OMIT_MEMORYDB
            var isMemdb = false;
#else
            var isMemdb = (zFilename == ":memory:" || isTempDb && db.sqlite3TempInMemory());
#endif
            Debug.Assert(db != null);
            Debug.Assert(pVfs != null);
            Debug.Assert(MutexEx.Held(db.Mutex));
            Debug.Assert(((uint)flags & 0xff) == (uint)flags);   // flags fit in 8 bits
            // Only a BTREE_SINGLE database can be BTREE_UNORDERED
            Debug.Assert((flags & OPEN.UNORDERED) == 0 || (flags & OPEN.SINGLE) != 0);
            // A BTREE_SINGLE database is always a temporary and/or ephemeral
            Debug.Assert((flags & OPEN.SINGLE) == 0 || isTempDb);
            if ((db.flags & sqlite3b.SQLITE.NoReadlock) != 0)
                flags |= OPEN.NO_READLOCK;
            if (isMemdb)
                flags |= OPEN.MEMORY;
            if ((vfsFlags & VFSOPEN.MAIN_DB) != 0 && (isMemdb || isTempDb))
                vfsFlags = (vfsFlags & ~VFSOPEN.MAIN_DB) | VFSOPEN.TEMP_DB;
            p = new Btree();
            p.InTransaction = TRANS.NONE;
            p.DB = db;
#if !SQLITE_OMIT_SHARED_CACHE
            p.Locks.Tree = p;
            p.Locks.TableID = 1;
#endif
            BtShared shared = null;          // Shared part of btree structure
            MutexEx mutexOpen = null;  // Prevents a race condition.
#if !SQLITE_OMIT_SHARED_CACHE && !SQLITE_OMIT_DISKIO
            // If this Btree is a candidate for shared cache, try to find an existing BtShared object that we can share with
            if (!isMemdb && !isTempDb)
            {
                if ((vfsFlags & VFSOPEN.SHAREDCACHE) != 0)
                {
                    p.Sharable = true;
                    string zPathname;
                    rc = pVfs.xFullPathname(zFilename, out zPathname);
                    mutexOpen = MutexEx.Alloc(MUTEX.STATIC_OPEN);
                    MutexEx.Enter(mutexOpen);
                    var mutexShared = MutexEx.Alloc(MUTEX.STATIC_MASTER);
                    MutexEx.Enter(mutexShared);
                    for (shared = SysEx.getGLOBAL<BtShared>(s_sqlite3SharedCacheList); shared != null; shared = shared.Next)
                    {
                        Debug.Assert(shared.nRef > 0);
                        if (string.Equals(zPathname, shared.Pager.sqlite3PagerFilename) && shared.Pager.sqlite3PagerVfs == pVfs)
                        {
                            for (var iDb = db.DBs - 1; iDb >= 0; iDb--)
                            {
                                var existingTree = db.AllocDBs[iDb].Tree;
                                if (existingTree != null && existingTree.Shared == shared)
                                {
                                    MutexEx.Leave(mutexShared);
                                    MutexEx.Leave(mutexOpen);
                                    p = null;
                                    return RC.CONSTRAINT;
                                }
                            }
                            p.Shared = shared;
                            shared.nRef++;
                            break;
                        }
                    }
                    MutexEx.Leave(mutexShared);
                }
#if DEBUG
                else
                    // In debug mode, we mark all persistent databases as sharable even when they are not.  This exercises the locking code and
                    // gives more opportunity for asserts(sqlite3_mutex_held()) statements to find locking problems.
                    p.Sharable = true;
#endif
            }
#endif
            if (shared == null)
            {
                // The following asserts make sure that structures used by the btree are the right size.  This is to guard against size changes that result
                // when compiling on a different architecture.
                Debug.Assert(sizeof(long) == 8 || sizeof(long) == 4);
                Debug.Assert(sizeof(ulong) == 8 || sizeof(ulong) == 4);
                Debug.Assert(sizeof(uint) == 4);
                Debug.Assert(sizeof(ushort) == 2);
                Debug.Assert(sizeof(Pgno) == 4);
                shared = new BtShared();
                rc = Pager.Open(pVfs, out shared.Pager, zFilename, EXTRA_SIZE, (Pager.PAGEROPEN)flags, vfsFlags, pageReinit, () => new MemPage());
                if (rc == RC.OK)
                    rc = shared.Pager.ReadFileHeader(zDbHeader.Length, zDbHeader);
                if (rc != RC.OK)
                    goto btree_open_out;
                shared.OpenFlags = flags;
                shared.DB = db;
                shared.Pager.SetBusyHandler(btreeInvokeBusyHandler, shared);
                p.Shared = shared;
                shared.Cursors = null;
                shared.Page1 = null;
                shared.ReadOnly = shared.Pager.IsReadonly;
#if SQLITE_SECURE_DELETE
pBt.secureDelete = true;
#endif
                shared.PageSize = (uint)((zDbHeader[16] << 8) | (zDbHeader[17] << 16));
                if (shared.PageSize < 512 || shared.PageSize > Pager.SQLITE_MAX_PAGE_SIZE || ((shared.PageSize - 1) & shared.PageSize) != 0)
                {
                    shared.PageSize = 0;
#if !SQLITE_OMIT_AUTOVACUUM
                    // If the magic name ":memory:" will create an in-memory database, then leave the autoVacuum mode at 0 (do not auto-vacuum), even if
                    // SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
                    // regular file-name. In this case the auto-vacuum applies as per normal.
                    if (zFilename != string.Empty && !isMemdb)
                    {
                        shared.AutoVacuum = (AUTOVACUUM.DEFAULT != AUTOVACUUM.NONE);
                        shared.IncrVacuum = (AUTOVACUUM.DEFAULT == AUTOVACUUM.INCR);
                    }
#endif
                    nReserve = 0;
                }
                else
                {
                    nReserve = zDbHeader[20];
                    shared.PageSizeFixed = true;
#if !SQLITE_OMIT_AUTOVACUUM
                    shared.AutoVacuum = ConvertEx.Get4(zDbHeader, 36 + 4 * 4) != 0;
                    shared.IncrVacuum = ConvertEx.Get4(zDbHeader, 36 + 7 * 4) != 0;
#endif
                }
                rc = shared.Pager.SetPageSize(ref shared.PageSize, nReserve);
                if (rc != RC.OK)
                    goto btree_open_out;
                shared.UsableSize = (ushort)(shared.PageSize - nReserve);
                Debug.Assert((shared.PageSize & 7) == 0);  // 8-byte alignment of pageSize
#if !SQLITE_OMIT_SHARED_CACHE && !SQLITE_OMIT_DISKIO
                // Add the new BtShared object to the linked list sharable BtShareds.
                if (p.Sharable)
                {
                    MutexEx mutexShared;
                    shared.nRef = 1;
                    mutexShared = MutexEx.Alloc(MUTEX.STATIC_MASTER);
                    if (MutexEx.SQLITE_THREADSAFE && MutexEx.WantsCoreMutex)
                        shared.Mutex = MutexEx.Alloc(MUTEX.FAST);
                    MutexEx.Enter(mutexShared);
                    shared.Next = SysEx.getGLOBAL<BtShared>(s_sqlite3SharedCacheList);
                    SysEx.setGLOBAL<BtShared>(s_sqlite3SharedCacheList, shared);
                    MutexEx.Leave(mutexShared);
                }
#endif
            }
#if !SQLITE_OMIT_SHARED_CACHE && !SQLITE_OMIT_DISKIO
            // If the new Btree uses a sharable pBtShared, then link the new Btree into the list of all sharable Btrees for the same connection.
            // The list is kept in ascending order by pBt address.
            Btree existingTree2;
            if (p.Sharable)
                for (var i = 0; i < db.DBs; i++)
                    if ((existingTree2 = db.AllocDBs[i].Tree) != null && existingTree2.Sharable)
                    {
                        while (existingTree2.Prev != null) { existingTree2 = existingTree2.Prev; }
                        if (p.Shared.Version < existingTree2.Shared.Version)
                        {
                            p.Next = existingTree2;
                            p.Prev = null;
                            existingTree2.Prev = p;
                        }
                        else
                        {
                            while (existingTree2.Next != null && existingTree2.Next.Shared.Version < p.Shared.Version)
                                existingTree2 = existingTree2.Next;
                            p.Next = existingTree2.Next;
                            p.Prev = existingTree2;
                            if (p.Next != null)
                                p.Next.Prev = p;
                            existingTree2.Next = p;
                        }
                        break;
                    }
#endif
            rTree = p;
        //
        btree_open_out:
            if (rc != RC.OK)
            {
                if (shared != null && shared.Pager != null)
                    shared.Pager.Close();
                shared = null;
                p = null;
                rTree = null;
            }
            else
            {
                // If the B-Tree was successfully opened, set the pager-cache size to the default value. Except, when opening on an existing shared pager-cache,
                // do not change the pager-cache size.
                if (p.GetSchema(0, null, null) == null)
                    p.Shared.Pager.SetCacheSize(SQLITE_DEFAULT_CACHE_SIZE);
            }
            if (mutexOpen != null)
            {
                Debug.Assert(MutexEx.Held(mutexOpen));
                MutexEx.Leave(mutexOpen);
            }
            return rc;
        }
コード例 #10
0
 private static void pcache1EnterMutex(PGroup X)
 {
     MutexEx.Enter(X.mutex);
 }