Esempio n. 1
0
            /// <summary>
            /// Increment shared instance id and return a process buffer with new Wpid
            /// </summary>
            /// <returns></returns>
            public ProcessConfigRecord CreateNew()
            {
                using (var txn = Environment.BeginTransaction())
                {
                    while (true)
                    {
                        // ReSharper disable once ImpureMethodCallOnReadonlyValueField
                        var newInsatnceId = unchecked ((uint)SharedRecord._processBuffer.InterlockedIncrementInt32(ProcessConfigRecord.SharedInstanceIdCounterOffset));
                        try
                        {
                            // We try to increment instance id instead of reuse existing
                            // At some point after running for very very long time it might overflow
                            // and start from zero again - this is fine.
                            if (_processDb.TryGet(txn, ref newInsatnceId, out BufferRef bufferRef))
                            {
                                continue;
                            }

                            bufferRef = Allocate(txn, 0, out var fromFreeList, null);
                            _processDb.Put(txn, newInsatnceId, bufferRef, TransactionPutOptions.NoOverwrite);
                            txn.Commit();
                            if (!fromFreeList)
                            {
                                Environment.Sync(true);
                            }

                            var result = _buckets[bufferRef];
                            if (fromFreeList)
                            {
                                // in Delete we clear the buffer after commit, there is small chance a process died after commit but before cleaning
                                result.Clear(0, result.Length);
                            }
                            else
                            {
                                Debug.Assert(result.IsFilledWithValue(0), "a new ProcessConfig buffer must be clean.");
                            }

                            result.WriteInt64(ProcessConfigRecord.WpidOffset, Wpid.Create(newInsatnceId));
                            var record = new ProcessConfigRecord(result);
                            return(record);
                        }
                        catch (Exception ex)
                        {
                            txn.Abort();
                            Trace.TraceError(ex.ToString());
                            throw;
                        }
                    }
                }
            }
Esempio n. 2
0
            public ProcessConfigStorage(string directoryPath)
                : base(directoryPath, StartupConfig.ProcessConfigEnvFlags, default, ProcessConfigRecord.BufferSize,
                       1024L * 1024 * 1024) // 1GB is way too much but it takes no resources above actually used
            {
                // BRA dbs and _env are set in base class

                // InstanceId -> BufferRef
                _processDb = Environment.OpenDatabase("_processConfig",
                                                      new DatabaseConfig(DbFlags.Create | DbFlags.IntegerKey));

                _buckets = new SharedMemoryBuckets(directoryPath, ProcessConfigRecord.BufferSize, 0);

                using (var txn = Environment.BeginTransaction())
                {
                    try
                    {
                        uint sharedInstanceId = 0;

                        if (_processDb.TryGet(txn, ref sharedInstanceId, out BufferRef sharedBufferRef))
                        {
                            txn.Abort();
                        }
                        else
                        {
                            sharedBufferRef = Allocate(txn, 0, out var fromFreeList, null);
                            _processDb.Put(txn, sharedInstanceId, sharedBufferRef, TransactionPutOptions.NoOverwrite);
                            txn.Commit();
                            if (!fromFreeList)
                            {
                                Environment.Sync(true);
                            }
                        }

                        SharedRecord = new ProcessConfigRecord(_buckets[sharedBufferRef]);
                    }
                    catch (Exception ex)
                    {
                        txn.Abort();
                        Trace.TraceError(ex.ToString());
                        throw;
                    }
                }
            }
Esempio n. 3
0
            public bool Delete(ProcessConfigRecord processConfigRecord)
            {
                if (!processConfigRecord.IsValid)
                {
                    return(false);
                }
                using (var txn = Environment.BeginTransaction())
                {
                    var wpid = processConfigRecord.Wpid;
                    // Debug.Assert(!IsWpidAlive(processConfigRecord));

                    uint insatnceId = wpid.InstanceId;

                    try
                    {
                        // We try to increment instance id instead of reuse existing
                        // At some point after running for very very long time it might overflow
                        // and start from zero again - this is fine.
                        if (!_processDb.TryGet(txn, ref insatnceId, out BufferRef bufferRef))
                        {
                            // was already deleted
                            // TODO (?) throw? review
                            txn.Abort();
                            return(false);
                        }

                        Free(txn, bufferRef);
                        _processDb.Delete(txn, insatnceId);
                        txn.Commit();

                        var db = _buckets[bufferRef];
                        db.Clear(0, db.Length);
                        return(true);
                    }
                    catch (Exception ex)
                    {
                        txn.Abort();
                        Trace.TraceError(ex.ToString());
                        throw;
                    }
                }
            }