Beispiel #1
0
        protected void Application_Start()
        {
            EnvironmentHandle.Register();

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            BundleTable.EnableOptimizations = true;
        }
        private LMDBEnvironment(string directory,
                                LMDBEnvironmentFlags openFlags = LMDBEnvironmentFlags.None,
                                UnixAccessMode accessMode      = UnixAccessMode.Default,
                                bool disableWriterThread       = false,
                                bool disableReadTxnAutoreset   = false)
        {
            NativeMethods.AssertExecute(NativeMethods.mdb_env_create(out var envHandle));
            _handle     = envHandle;
            _accessMode = accessMode;
            _disableReadTxnAutoreset = disableReadTxnAutoreset;

            _directory = directory;
            _openFlags = openFlags;

            try
            {
                CreateDirectoryIfMissing();
            }
            catch
            {
                NativeMethods.mdb_env_close(envHandle);
                throw;
            }

            MaxDatabases = Config.DbEnvironment.DefaultMaxDatabases;

            // Writer Task
            // In the current process writes are serialized via the blocking queue
            // Accross processes, writes are synchronized via WriteTxnGate (TODO!)
            _cts = new CancellationTokenSource();

            if (!disableWriterThread)
            {
                _writeQueue = new BlockingCollection <Delegates>();
                var threadStart = new ThreadStart(() =>
                {
                    while (!_writeQueue.IsCompleted)
                    {
                        try
                        {
                            // BLOCKING
                            var delegates = _writeQueue.Take(_cts.Token);

                            var transactionImpl = TransactionImpl.Create(this, TransactionBeginFlags.ReadWrite);

                            try
                            {
                                // TODO for some methods such as mbd_put we should have a C method
                                // that begins/end txn automatically
                                // we still need to pass call to it here, but we could avoid txn creation
                                // and two P/Invokes

                                var txn = new Transaction(transactionImpl);

                                if (delegates.WriteFunction != null)
                                {
                                    var res = delegates.WriteFunction(txn);
                                    delegates.Tcs?.SetResult(res);
                                }
                                else if (delegates.WriteAction != null)
                                {
                                    delegates.WriteAction(txn);
                                    delegates.Tcs?.SetResult(null);
                                }
                                else
                                {
                                    Environment.FailFast("Wrong writer thread setup");
                                }
                            }
                            catch (Exception e)
                            {
                                delegates.Tcs?.SetException(e);
                                transactionImpl?.Abort();
                            }
                            finally
                            {
                                transactionImpl?.Dispose();
                            }
                        }
                        catch (InvalidOperationException)
                        {
                        }
                    }

                    _writeTaskCompletion.SetResult(null);
                });
                var writeThread = new Thread(threadStart)
                {
                    Name         = "LMDB Writer thread",
                    IsBackground = true
                };
                writeThread.Start();
            }
        }