/// <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(); }
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); }