コード例 #1
0
            /// <summary>
            /// Call to lock box increases lock
            /// </summary>
            /// <param name="wrappedConnection"></param>
            public SQLiteLockBox(LockableSQLiteConnection wrappedConnection)
            {
                this.m_connection = wrappedConnection;
                Monitor.Enter(this.m_connection.m_lockObject);
#if DEBUG
                this.m_connection.m_claimedBy = Thread.CurrentThread.ManagedThreadId;
#endif
                this.m_connection.m_lockCount++;
                this.m_connection.m_availableEvent.Reset();
            }
コード例 #2
0
        /// <summary>
        /// Register connection
        /// </summary>
        private void RegisterConnection(LockableSQLiteConnection conn)
        {
            List <LockableSQLiteConnection> connections = this.GetOrRegisterConnections(conn.ConnectionString);

            lock (s_lockObject)
            {
                connections.Add(conn);
                this.m_connectionPool.Remove(conn); // Just in-case
                // Lock this connection so I know if I can bypass later
                Monitor.Enter(conn);

                this.m_tracer.TraceVerbose("++ {0} ({1})", conn.DatabasePath, connections.Count);
            }
        }
コード例 #3
0
        /// <summary>
        /// Get the specified connection from the pool or create one
        /// </summary>
        private LockableSQLiteConnection GetOrCreatePooledConnection(ConnectionString dataSource, bool isReadonly)
        {
            // Pool exists?
            var connectionPool = this.GetConnectionPool(dataSource.Name);

            // Get the platform
            ISQLitePlatform platform = ApplicationServiceContext.Current.GetService <ISQLitePlatform>();

            // Try to lock global (make sure another process isn't hogging it)

            LockableSQLiteConnection retVal = null;

            if (isReadonly) // Readonly we can use any connection we like
            {
                retVal = connectionPool.GetEntered() ??
                         connectionPool.GetFree();
                if (retVal == null) // Create a connection
                {
                    retVal = new LockableSQLiteConnection(platform, dataSource, SQLiteOpenFlags.ReadOnly | SQLiteOpenFlags.FullMutex);
                    retVal.Execute("PRAGMA synchronous = 1");
                    connectionPool.Add(retVal);
                    //retVal.Wait();
                }
                else
                {
                    retVal.Wait(); // Wait for connection to become available
                }
            }
            else // We want write
            {
                retVal = connectionPool.GetWritable(); // Might be writable connection available
                if (retVal == null)
                {
                    retVal = new LockableSQLiteConnection(platform, dataSource, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.Create);
                    retVal.Execute("PRAGMA synchronous = 1");
                    retVal = connectionPool.AddUnique(retVal, o => !o.IsReadonly);
                    retVal.Wait();
                }
                else  // Wait for the connection to become available
                {
                    retVal.Wait();
                }
            }

            return(retVal);
        }
コード例 #4
0
        /// <summary>
        /// Unregister connection
        /// </summary>
        private void UnregisterConnection(LockableSQLiteConnection conn)
        {
            List <LockableSQLiteConnection> connections = this.GetOrRegisterConnections(conn.ConnectionString);

            lock (s_lockObject)
            {
                Monitor.Exit(conn);
                connections.Remove(conn);

                // Add connection back onto the pool
                if (conn.Persistent)
                {
                    this.m_connectionPool.Add(conn);
                }

                this.m_tracer.TraceVerbose("-- {0} ({1})", conn.DatabasePath, connections.Count);
            }
        }
コード例 #5
0
        /// <summary>
        /// Gets or sets the reset event for the particular database
        /// </summary>
        private ManualResetEventSlim GetOrRegisterResetEvent(LockableSQLiteConnection connection)
        {
            ManualResetEventSlim retVal = null;

            if (!this.m_connections.TryGetValue(connection.ConnectionString.Name, out retVal))
            {
                retVal = new ManualResetEventSlim(true);
                lock (s_lockObject)
                    if (!this.m_connections.ContainsKey(connection.ConnectionString.Name))
                    {
                        this.m_connections.Add(connection.ConnectionString.Name, retVal);
                    }
                    else
                    {
                        retVal = this.m_connections[connection.ConnectionString.Name];
                    }
            }
            return(retVal);
        }
コード例 #6
0
        /// <summary>
        /// Get or create a pooled connection
        /// </summary>
        private LockableSQLiteConnection GetOrCreatePooledConnection(ConnectionString 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.Name, 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.ConnectionString.Name == dataSource.Name);
                }
                else
                {
                    if (!this.m_writeConnections.TryGetValue(dataSource.Name, 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.Name, 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);
            }
        }