public void SetFlags(CacheFileFlags value, bool on)
        {
            DbRetVal ret;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->SetFlags(mpf, value, on ? 1 : 0);
            }
            Util.CheckRetVal(ret);
        }
        public void Sync()
        {
            DbRetVal ret;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->Sync(mpf);
            }
            Util.CheckRetVal(ret);
        }
        public void SetPageFlags(CachePage page, CachePagePutFlags flags)
        {
            DbRetVal ret;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->Set(mpf, (void *)page.data, flags);
            }
            Util.CheckRetVal(ret);
        }
        protected sealed internal override DB_MPOOLFILE *CheckDisposed()
        {
            // avoid multiple volatile memory access
            DB_MPOOLFILE *mpf = this.mpf;

            if (mpf == null)
            {
                throw new ObjectDisposedException(disposedStr);
            }
            return(mpf);
        }
        public CacheFileFlags GetFlags()
        {
            CacheFileFlags value;
            DbRetVal       ret;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->GetFlags(mpf, out value);
            }
            Util.CheckRetVal(ret);
            return(value);
        }
        void *GetPage(ref uint pageNo, DB_TXN *txp, CachePageGetFlags flags)
        {
            DbRetVal ret;
            void *   page;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->Get(mpf, ref pageNo, txp, flags, out page);
            }
            Util.CheckRetVal(ret);
            return(page);
        }
        public void SetPageCookie(ref DbEntry cookie)
        {
            DbRetVal ret;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                fixed(byte *cookieBufP = cookie.Buffer)
                {
                    cookie.dbt.data = cookieBufP + cookie.Start;
                    ret             = mpf->SetPageCookie(mpf, ref cookie.dbt);
                }
            }
            Util.CheckRetVal(ret);
        }
        public void Open(string fileName, int pageSize, CacheFileOpenFlags flags, int mode)
        {
            DbRetVal ret;

            byte[] fileBytes = null;
            Util.StrToUtf8(fileName, ref fileBytes);
            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                fixed(byte *filep = fileBytes)
                {
                    ret = mpf->Open(mpf, filep, flags, mode, unchecked ((uint)pageSize));
                }
            }
            Util.CheckRetVal(ret);
            this.pageSize = unchecked ((uint)pageSize);
        }
        public void GetPageCookie(out DbEntry cookie)
        {
            DbRetVal ret;
            DBT      cookieDbt;

            lock (rscLock) {
                DB_MPOOLFILE *mpf = CheckDisposed();
                ret = mpf->GetPageCookie(mpf, out cookieDbt);
            }
            Util.CheckRetVal(ret);
            if (cookieDbt.size != 0)
            {
                byte[] buffer = new byte[cookieDbt.size];
                Marshal.Copy((IntPtr)cookieDbt.data, buffer, 0, unchecked ((int)cookieDbt.size));
                cookie = DbEntry.Out(buffer);
            }
            else
            {
                cookie = new DbEntry();
            }
        }
        // should be run in a CER, under a lock on rscLock, and not throw exceptions
        DbRetVal ReleaseUnmanagedResources()
        {
            // don't touch the handle if this instance is owned by a database
            if (env == null)
            {
                return(DbRetVal.SUCCESS);
            }
            DB_MPOOLFILE *mpf = this.mpf;

            if (mpf == null)
            {
                return(DbRetVal.SUCCESS);
            }
            // DB_MPOOLFILE->Close() could be a lengthy call, so we call Disposed() first, and the
            // CER ensures that we reach DB_MPOOLFILE->Close() without external interruption.
            // This is OK because one must not use the handle after DB_MPOOLFILE->Close() was called,
            // regardless of the return value.
            Disposed();
            DbRetVal ret = mpf->Close(mpf, 0);

            return(ret);
        }