Esempio n. 1
0
        /// <summary>
        /// Un-register a readonly connection
        /// </summary>
        internal void RegisterReadonlyConnection(ReadonlySQLiteConnection conn)
        {
            List <LockableSQLiteConnection> connections = this.GetOrRegisterConnections(conn.DatabasePath);

            // Are there other connections that this thread owns?
            bool skipTrafficStop = false;
            WriteableSQLiteConnection writerConnection = null;

            lock (s_lockObject)
                skipTrafficStop = this.m_writeConnections.TryGetValue(conn.DatabasePath, out writerConnection) && Monitor.IsEntered(writerConnection) ||
                                  connections.Any(o => Monitor.IsEntered(o));
            if (!skipTrafficStop) // then we must adhere to traffic jams
            {
                var mre = this.GetOrRegisterResetEvent(conn.DatabasePath);
                mre.WaitOne();
                this.RegisterConnection(conn);
            }
        }
            /// <summary>
            /// Wrapper with lock
            /// </summary>
            public SQLiteConnectionWrapperLock(ReadonlySQLiteConnection wrappedConnection)
            {
                this.m_connection = wrappedConnection;
                Object lockObject = null;

                if (!m_lockBox.TryGetValue(wrappedConnection.DatabasePath, out lockObject))
                {
                    lockObject = new object();
                    lock (m_lockBox)
                        if (!m_lockBox.ContainsKey(wrappedConnection.DatabasePath))
                        {
                            m_lockBox.Add(wrappedConnection.DatabasePath, lockObject);
                        }
                        else
                        {
                            lockObject = m_lockBox[wrappedConnection.DatabasePath];
                        }
                }

                Monitor.Enter(lockObject);
                SQLiteConnectionManager.Current.RegisterReadonlyConnection(this.m_connection);
                this.m_connection.m_lockCount++;
            }
Esempio n. 3
0
 /// <summary>
 /// Un-register a readonly connection
 /// </summary>
 internal void UnregisterReadonlyConnection(ReadonlySQLiteConnection conn)
 {
     this.UnregisterConnection(conn);
 }
Esempio n. 4
0
        /// <summary>
        /// Get or create a pooled connection
        /// </summary>
        private LockableSQLiteConnection GetOrCreatePooledConnection(string dataSource, bool isReadonly)
        {
            // First is there a connection already?
            var connections = this.GetOrRegisterConnections(dataSource);
            WriteableSQLiteConnection writeConnection = null;

            lock (s_lockObject)
            {
                if (this.m_writeConnections.TryGetValue(dataSource, out writeConnection))
                {
                    if (Monitor.IsEntered(writeConnection))
                    {
                        return(writeConnection);
                    }
                }
                var conn = connections.FirstOrDefault(o => Monitor.IsEntered(o));
                if (conn != null)
                {
                    return(conn);
                }
            }


            ISQLitePlatform platform = ApplicationContext.Current.GetService <ISQLitePlatform>();

            lock (s_lockObject)
            {
                LockableSQLiteConnection retVal = null;
                if (isReadonly)
                {
                    retVal = this.m_connectionPool.OfType <ReadonlySQLiteConnection>().FirstOrDefault(o => o.DatabasePath == dataSource);
                }
                else
                {
                    if (!this.m_writeConnections.TryGetValue(dataSource, out writeConnection)) // Writeable connection can only have one in the pool so if it isn't there make sure it isn't in the current
                    {
                        writeConnection = new WriteableSQLiteConnection(platform, dataSource, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.Create)
                        {
                            Persistent = true
                        };
                        writeConnection.Execute("PRAGMA synchronous = 1");
                        //writeConnection.Execute("PRAGMA automatic_index = true");
                        //writeConnection.Execute("PRAGMA journal_mode = WAL");
                        this.m_writeConnections.Add(dataSource, writeConnection);
                    }

                    retVal = writeConnection;
                }

                // Remove return value
                if (retVal != null)
                {
                    this.m_connectionPool.Remove(retVal);
                }
                else if (isReadonly)
                {
                    retVal = new ReadonlySQLiteConnection(platform, dataSource, SQLiteOpenFlags.ReadOnly | SQLiteOpenFlags.FullMutex)
                    {
                        Persistent = true
                    };
                    //retVal.Execute("PRAGMA threads = 2");
                }
                else
                {
                    throw new InvalidOperationException("Should not be here");
                }
                return(retVal);
            }
        }