Example #1
0
        }     // end Transfer()

        private ExceptionGuard _CompleteTransfer()
        {
            lock ( m_syncRoot )
            {
                _CheckDisposed();
                var eg = new ExceptionGuard(m_disposables);
                m_disposables = new List <IDisposable>();
                return(eg);
            }
        } // end _CompleteTransfer()
Example #2
0
            }     // end CommitTransfer()

            /// <summary>
            ///    To be called in the even that the transfer was not able to be
            ///    committed. (For instance, if the originating thread failed to post the
            ///    transfer to the receiving thread.)
            /// </summary>
            internal void CancelTransferIfNecessary()
            {
                lock ( m_syncRoot )
                {
                    if (null == m_source)
                    {
                        return; // transfer is already committed or redeemed.
                    }
                    // If the destination thread is stuck waiting, we'll prepare an empty
                    // ExceptionGuard to give to it and then unblock it.
                    m_transferred = new ExceptionGuard();
                    m_source      = null;
                    Monitor.PulseAll(m_syncRoot);
                } // end lock
            }     // end CancelTransferIfNecessary()
Example #3
0
            }     // end Redeem()

            public void CommitTransfer()
            {
                lock ( m_syncRoot )
                {
                    if (null == m_source)
                    {
                        throw new InvalidOperationException("Transfer already committed.");
                    }

                    m_transferred = m_source._CompleteTransfer();
                    m_source      = null;

                    // The thread that will Redeem() the transfer may or may not be
                    // waiting. If it is, signal it:
                    Monitor.PulseAll(m_syncRoot);
                } // end lock
            }     // end CommitTransfer()
Example #4
0
            public ExceptionGuard Redeem()
            {
                lock ( m_syncRoot )
                {
                    if ((null == m_source) && (null == m_transferred))
                    {
                        throw new InvalidOperationException("Transfer already redeemed.");
                    }

                    if (null == m_transferred)
                    {
                        // We need to wait for the transfer to be committed by
                        // CommitTransfer().
                        Monitor.Wait(m_syncRoot);
                        Util.Assert(null != m_transferred);
                    }
                    // else the CommitTransfer call already went through.

                    var tmp = m_transferred;
                    m_transferred = null;
                    return(tmp);
                } // end lock
            }     // end Redeem()
Example #5
0
 internal TransferTicket(ExceptionGuard source)
 {
     m_source = source;
 }
Example #6
0
        } // end _PruneLogFiles()

        private static void _PruneFilesNotInUse(string dir, string pattern, long cbMaxSize)
        {
            const int MIN_LOG_BYTES = 1024 * 1024;

            if (cbMaxSize < MIN_LOG_BYTES)
            {
                Util.Fail("should not happen");   // safe to use Util.Fail here
                cbMaxSize = MIN_LOG_BYTES;
            }

            using (ExceptionGuard disposer = new ExceptionGuard())
            {
                DirectoryInfo     di        = new DirectoryInfo(dir);
                FileSystemInfo[]  fsis      = di.GetFileSystemInfos(pattern);
                List <FileInfo>   files     = new List <FileInfo>(fsis.Length);
                List <FileStream> fileLocks = new List <FileStream>(fsis.Length);
                disposer.ProtectAll(fileLocks);   // it does not make a copy of the list, so it's okay that we haven't put anything in yet.
                long totalSize = 0;
                foreach (FileSystemInfo fsi in fsis)
                {
                    FileInfo fi = fsi as FileInfo;
                    if (null != fi)
                    {
                        // We only count not-in-use files against our disk limit. If the
                        // file is not in use, this will "lock" it (making it appear
                        // in-use to anybody else) and put the resulting FileStream in the
                        // fileLocks list.
                        if (_FileNotInUse(fi, fileLocks))
                        {
#if DEBUG_LOG_PRUNING
                            Trace("File \"{0}\" is NOT in use. (it will be considered for pruning)", fi.FullName);
#endif
                            fi.Refresh(); // in case _FileNotInUse finalized it.
                            totalSize += fi.Length;
                            files.Add(fi);
                        }
#if DEBUG_LOG_PRUNING
                        else
                        {
                            Trace("File \"{0}\" is in use.", fi.FullName);
                        }
#endif
                    }
                }

                if (totalSize <= cbMaxSize)
                {
                    // Don't need to prune anything.
                    return;
                }

                // Sort by age: oldest first.
                files.Sort((x, y) => x.CreationTime.CompareTo(y.CreationTime));

                long cbDeletedSoFar = 0;
                long cbNeedToDelete = totalSize - cbMaxSize;
                int  idxCandidate   = 0;
                while ((idxCandidate < files.Count) &&
                       (cbDeletedSoFar < cbNeedToDelete))
                {
                    if (_TryDeleteOldFile(files[idxCandidate].FullName))
                    {
                        cbDeletedSoFar += files[idxCandidate].Length;
                    }
                    idxCandidate++;
                }

                if (cbDeletedSoFar < cbNeedToDelete)
                {
                    Trace("Warning: could not delete enough log files matching \"{0}\" from \"{1}\" to get under the limit of {2}.",
                          pattern,
                          dir,
                          Util.FormatByteSize(cbMaxSize));
                }
            } // end using( disposer ) <-- the files will actually get deleted here when we close the FileStream handles.
        }     // end _PruneFilesNotInUse()