Пример #1
0
        /// <summary>
        /// Tries to write an object to the shared memory stream.
        /// </summary>
        /// <param name="obj">Object to write to the shared memory stream</param>
        /// <param name="nodeCount">The node count.</param>
        /// <returns>
        /// True if the writes occured; otherwise false.
        /// </returns>
        /// <exception cref="SerializationException">An object in the graph of type parameter <typeparamref name="T" /> is not marked as serializable.</exception>
        private bool TryWriteObject(T obj, out int nodeCount)
        {
            var data   = Serialize(obj);
            var lenbuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(data.Length));

            nodeCount = CalculateNodeToUse(lenbuf.Length) + CalculateNodeToUse(data.Length);

            // Atomic operation
            if (DynamicSpin.Acquire(_spinName))
            {
                try
                {
                    // Writes length of the data followed by the data, so we will know how many data de read.
                    BaseStream.Write(lenbuf, 0, lenbuf.Length);
                    BaseStream.Write(data, 0, data.Length);
                    Flush();
                    return(true);
                }
                finally
                {
                    DynamicSpin.Release(_spinName);
                }
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
 /// <summary>
 /// Releases unmanaged and - optionally - managed resources.
 /// </summary>
 public void Dispose()
 {
     if (_spinName != null)
     {
         DynamicSpin.Release(_spinName);
     }
     Dispose(true);
     GC.SuppressFinalize(this);
 }
Пример #3
0
        public void Spin_Simple()
        {
            string spinName = "test";

            if (DynamicSpin.Acquire(spinName))
            {
                DynamicSpin.Release(spinName);
            }
            else
            {
                Assert.Fail();
            }
        }
        /// <summary>
        /// Releases all resources used by the <see cref="T:System.IO.Stream" />.
        /// </summary>
        void IDisposable.Dispose()
        {
            if (_spinNameRead != null)
            {
                DynamicSpin.Release(_spinNameRead);
            }
            if (_spinNameWrite != null)
            {
                DynamicSpin.Release(_spinNameWrite);
            }

            if (_circularBuffer != null)
            {
                _circularBuffer.Dispose();
            }
        }
Пример #5
0
        public void Spin_Locked()
        {
            string spinName = "test";

            if (DynamicSpin.Acquire(spinName))
            {
                if (DynamicSpin.Acquire(spinName))
                {
                    Assert.Fail();
                }
                DynamicSpin.Release(spinName);
            }
            else
            {
                Assert.Fail();
            }
        }
Пример #6
0
        /// <summary>
        /// Reads the next object from the shared memory stream. This method blocks until an object is sent
        /// or the shared memory stream is disconnected.
        /// </summary>
        /// <returns>The next object read from the shared memory stream, or <c>null</c> if the shared memory stream disconnected.</returns>
        /// <exception cref="SerializationException">An object in the graph of type parameter <typeparamref name="T"/> is not marked as serializable.</exception>
        public T ReadObject()
        {
            if (DynamicSpin.Acquire(_spinName))
            {
                try
                {
                    int len = 0;
                    do
                    {
                        len = ReadLength();
                    } while (len == 0);

                    return(ReadObject(len));
                }
                finally
                {
                    DynamicSpin.Release(_spinName);
                }
            }
            else
            {
                throw new TimeoutException("Unable to read the underlying stream, The read operation has timed out.");
            }
        }
        /// <summary>
        /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
        /// </summary>
        /// <param name="buffer">An array of bytes. This method copies <paramref name="count" /> bytes from <paramref name="buffer" /> to the current stream.</param>
        /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the current stream.</param>
        /// <param name="count">The number of bytes to be written to the current stream.</param>
        /// <exception cref="System.ArgumentNullException">buffer</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">count or offset</exception>
        /// <exception cref="System.IO.IOException">If there is not enougth free space to write data.</exception>
        /// <exception cref="System.OutOfMemoryException">If the underlying buffer is full.</exception>
        /// <exception cref="System.TimeoutException">If it exceed the time allowed to write data.</exception>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (!CanWrite)
            {
                throw new NotSupportedException("Write is not supported.");
            }

            byte[] tempBuffer;
            if (count < buffer.Length - offset)
            {
                tempBuffer = new byte[count];
                Array.Copy(buffer, offset, tempBuffer, 0, count);
            }
            else
            {
                tempBuffer = buffer;
            }

            int written = 0;
            int toWrite = tempBuffer.Length - offset;

#if DEBUG
            int freeSize = (_circularBuffer.FreeNodeCount) * _circularBuffer.NodeBufferSize;
            Debug.WriteLine("Buffer to write: " + tempBuffer.Length + " bytes, Free space available: " + _circularBuffer.FreeNodeCount + "x" + _circularBuffer.NodeBufferSize + "=" + freeSize + " bytes", "Information");
#endif

            //bool hasTimedOut = false;

            // Enter critial path
            Thread.BeginCriticalRegion();

            // Wait for other threads to finish writing
            if (DynamicSpin.Acquire(_spinNameWrite))
            {
                try
                {
                    // Writes into the buffer, if the buffer is full, it will wait until new node are freed.
                    //Stopwatch sw = new Stopwatch();
                    //sw.Start();
                    while (written < toWrite && !_circularBuffer.ShuttingDown)
                    {
                        int wr = _circularBuffer.Write(tempBuffer, offset, _readTimeout);
                        offset  += wr;
                        written += wr;

                        // Writes timeout
                        //if (sw.ElapsedMilliseconds > _writeTimeout)
                        //{
                        //    hasTimedOut = true;
                        //    break;
                        //}
                    }
                    //sw.Stop();
                }
                finally
                {
                    // Be shure to release the spin.
                    DynamicSpin.Release(_spinNameWrite);
                }
            }
            Thread.EndCriticalRegion();

            //if (hasTimedOut)
            //    throw new TimeoutException(string.Format("Waited {0} miliseconds", _readTimeout));

#if DEBUG
            if (written != 0)
            {
                Debug.WriteLine(written + " byte(s) have been written to the underlying circular buffer.", "Information");
            }
#endif
        }
        /// <summary>
        /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
        /// </summary>
        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced by the bytes read from the current source.</param>
        /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read from the current stream.</param>
        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
        /// <returns>
        /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">buffer</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">count or offset</exception>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (!CanRead)
            {
                throw new NotSupportedException("Read is not supported.");
            }

            int red = 0;

            //bool hasTimedOut = false;

            // Enter critial path
            Thread.BeginCriticalRegion();

            // Wait for other threads to finish writing
            if (DynamicSpin.Acquire(_spinNameRead))
            {
                try
                {
                    //Stopwatch sw = new Stopwatch();
                    //sw.Start();
                    while (red < count && _circularBuffer.HasNodeToRead && !_circularBuffer.ShuttingDown)
                    {
                        int rd = _circularBuffer.Read(buffer, offset, _readTimeout);
                        offset += rd;
                        red    += rd;

                        //// Reads timeout
                        //if (sw.ElapsedMilliseconds > _readTimeout)
                        //{
                        //    hasTimedOut = true;
                        //    break;
                        //}
                    }
                    //sw.Stop();
                }
                finally
                {
                    // Be shure to release the spin.
                    DynamicSpin.Release(_spinNameRead);
                }
            }
            Thread.EndCriticalRegion();

            //if (hasTimedOut)
            //    throw new TimeoutException(string.Format("Waited {0} miliseconds", _readTimeout));


#if DEBUG
            if (red != 0)
            {
                Debug.WriteLine(red + " byte(s) have been red from the underlying circular buffer.", "Information");
            }
#endif

            return(red);
        }