예제 #1
0
        /// <summary>Construct the session pool.</summary>
        /// <remarks>You should only create a single instance of this class.</remarks>
        /// <param name="settings">Database settings.</param>
        /// <param name="arrTypes">The array of record types.
        /// In every session returned by this pool, the corresponding tables will be already opened for you.</param>
        public SessionPool(EsentDatabase.Settings settings, params Type[] arrTypes)
        {
            folderDatabase = settings.databasePath;

            m_serializer = new EseSerializer(settings, arrTypes.Length, null);

            SessionLimit = Math.Max(settings.maxConcurrentSessions, 0);

            if (SessionLimit > 0)
            {
                m_semaphore = new Semaphore(SessionLimit, SessionLimit);
            }

            m_allSessions = new HashSet <SerializerSession>();

            m_freeSessions = new Stack <SerializerSession>();

            m_recordTypes = arrTypes.ToList();

            m_serializer.EnsureDatabaseExists();
        }
예제 #2
0
        iSerializerSession GetSessionImpl(eSessionCooperativeLevel coopLevel)
        {
            if (singleSessionPerThread && null != threadSession)
            {
                if (threadSession.cooperativeLevel != coopLevel)
                {
                    throw new Exception("You can't get sessions with different cooperative levels on the same thread at the same time");
                }
                threadSession.AddRef();
                return(threadSession);
            }

            if (null != m_semaphore)
            {
                if (!m_semaphore.WaitOne(tsWaitForFreeSession))
                {
                    throw new TimeoutException("SessionPool.tsWaitForFreeSession timeout exceeded.");
                }
            }

            SerializerSession nativeSession = null;
            bool bNewSession = false;

            lock (this.syncRoot)
            {
                if (m_freeSessions.Count > 0)
                {
                    nativeSession = m_freeSessions.Pop();
                }
                else
                {
                    m_serializer.EnsureDatabaseExists();

                    nativeSession = new SerializerSession(m_serializer);
                    m_allSessions.Add(nativeSession);
                    bNewSession = true;

                    if (m_bFirstSession)
                    {
                        m_bFirstSession = false;

                        if (null != this.updateSchema)
                        {
                            DatabaseSchemaUpdater updater = new DatabaseSchemaUpdater(nativeSession);
                            this.updateSchema(updater);
                        }
                    }
                }
            }

            if (bNewSession)
            {
                foreach (var t in m_recordTypes)
                {
                    nativeSession.AddType(t);
                }
                TraceInfo("GetSessionImpl: constructed a new session");
            }

            SerializerSessionImpl sessionWrapper = new SerializerSessionImpl(nativeSession, this, coopLevel);

            sessionCooperativeLockEnter(sessionWrapper);
            sessionWrapper.AddRef();

            if (singleSessionPerThread)
            {
                threadSession = sessionWrapper;
            }

            // Bind new session to the current thread
            nativeSession.setThread();

            return(sessionWrapper);
        }