Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / _PooledStream.cs / 3 / _PooledStream.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net
{
using System;
using System.Net.Sockets;
using System.IO;
using System.Diagnostics;
using System.Security.Permissions;
using System.Threading;
internal class PooledStream : Stream {
// managed pooling lifetime controls
private bool m_CheckLifetime; // true when the connection is only to live for a specific timespan
private TimeSpan m_Lifetime; // the timespan the connection is to live for
private DateTime m_CreateTime; // when the connection was created.
private bool m_ConnectionIsDoomed;// true when the connection should no longer be used.
// managed pooling
private ConnectionPool m_ConnectionPool; // the pooler that the connection came from
private WeakReference m_Owner; // the owning object, when not in the pool.
private int m_PooledCount; // the number of times this object has been pushed into the pool less the number of times it's been popped (0 == inPool)
// connection info
private bool m_Initalizing; // true while we're creating the stream
private IPAddress m_ServerAddress; // IP address of server we're connected to
private NetworkStream m_NetworkStream; // internal stream for socket
private Socket m_AbortSocket; // in abort scenarios, used to abort connect
private Socket m_AbortSocket6; // in abort scenarios, used to abort connect
private bool m_JustConnected;
internal PooledStream(object owner) : base() { // non-pooled constructor
m_Owner = new WeakReference(owner);
m_PooledCount = -1;
m_Initalizing = true;
m_NetworkStream = new NetworkStream();
m_CreateTime = DateTime.UtcNow;
}
internal PooledStream(ConnectionPool connectionPool, TimeSpan lifetime, bool checkLifetime) : base () { // pooled constructor
m_ConnectionPool = connectionPool;
m_Lifetime = lifetime;
m_CheckLifetime = checkLifetime;
m_Initalizing = true;
m_NetworkStream = new NetworkStream();
m_CreateTime = DateTime.UtcNow;
}
internal bool JustConnected {
get{
if (m_JustConnected)
{
m_JustConnected = false;
return true;
}
return false;
}
}
internal IPAddress ServerAddress {
get {
return m_ServerAddress;
}
}
internal bool IsInitalizing {
get {
return m_Initalizing;
}
}
internal bool CanBePooled {
get {
if (m_Initalizing) {
GlobalLog.Print("PooledStream#" + ValidationHelper.HashString(this) + "::CanBePooled " + "init: true");
return true;
}
if (!m_NetworkStream.Connected) {
GlobalLog.Print("PooledStream#" + ValidationHelper.HashString(this) + "::CanBePooled " + "not-connected: false");
return false;
}
WeakReference weakref = m_Owner;
bool flag = (!m_ConnectionIsDoomed && ((null == weakref) || !weakref.IsAlive));
GlobalLog.Print("PooledStream#" + ValidationHelper.HashString(this) + "::CanBePooled " + "flag: " + flag.ToString());
return (flag);
}
set {
m_ConnectionIsDoomed |= !value;
}
}
internal bool IsEmancipated {
get {
WeakReference owner = m_Owner;
bool value = (0 >= m_PooledCount) && (null == owner || !owner.IsAlive);
return value;
}
}
internal object Owner {
// We use a weak reference to the owning object so we can identify when
// it has been garbage collected without thowing exceptions.
get {
WeakReference weakref = m_Owner;
if ((null != weakref) && weakref.IsAlive) {
return weakref.Target;
}
return null;
}
set{
lock(this){
if(null != m_Owner){
m_Owner.Target = value;
}
}
}
}
internal ConnectionPool Pool {
get { return m_ConnectionPool; }
}
internal virtual ServicePoint ServicePoint {
get { return Pool.ServicePoint; }
}
private GeneralAsyncDelegate m_AsyncCallback;
internal bool Activate(object owningObject, GeneralAsyncDelegate asyncCallback)
{
return Activate(owningObject, asyncCallback != null, Timeout.Infinite, asyncCallback);
}
protected bool Activate(object owningObject, bool async, int timeout, GeneralAsyncDelegate asyncCallback)
{
GlobalLog.Assert(owningObject == Owner || Owner == null, "PooledStream::Activate|Owner is not the same as expected.");
try {
if (m_Initalizing) {
IPAddress address = null;
m_AsyncCallback = asyncCallback;
Socket socket = ServicePoint.GetConnection(this, owningObject, async, out address, ref m_AbortSocket, ref m_AbortSocket6, timeout);
if (socket != null) {
m_NetworkStream.InitNetworkStream(socket, FileAccess.ReadWrite);
m_ServerAddress = address;
m_Initalizing = false;
m_JustConnected = true;
m_AbortSocket = null;
m_AbortSocket6 = null;
return true;
}
return false;
}
else if (async && asyncCallback != null)
{
asyncCallback(owningObject, this);
}
return true;
} catch {
m_Initalizing = false;
throw;
}
}
internal void Deactivate() {
// Called when the connection is about to be placed back into the pool; this
m_AsyncCallback = null;
if (!m_ConnectionIsDoomed && m_CheckLifetime) {
// check lifetime here - as a side effect it will doom connection if
// it's lifetime has elapsed
CheckLifetime();
}
}
internal virtual void ConnectionCallback(object owningObject, Exception e, Socket socket, IPAddress address)
{
GlobalLog.Assert(owningObject == Owner || Owner == null, "PooledStream::ConnectionCallback|Owner is not the same as expected.");
object result = null;
if (e != null) {
m_Initalizing = false;
result = e;
} else {
try {
m_NetworkStream.InitNetworkStream(socket, FileAccess.ReadWrite);
result = this;
}
catch (Exception ex)
{
if (NclUtilities.IsFatal(ex))
throw;
result = ex;
}
catch {
throw;
}
m_ServerAddress = address;
m_Initalizing = false;
m_JustConnected = true;
}
if (m_AsyncCallback != null) {
m_AsyncCallback(owningObject, result);
}
m_AbortSocket = null;
m_AbortSocket6 = null;
}
protected void CheckLifetime() {
bool okay = !m_ConnectionIsDoomed;
if (okay) {
// Returns whether or not this object's lifetime has had expired.
// True means the object is still good, false if it has timed out.
// obtain current time
DateTime utcNow = DateTime.UtcNow;
// obtain timespan
TimeSpan timeSpan = utcNow.Subtract(m_CreateTime);
// compare timeSpan with lifetime, if equal or less,
// designate this object to be killed
m_ConnectionIsDoomed = (0 < TimeSpan.Compare(m_Lifetime, timeSpan));
}
}
///
/// Updates the lifetime of the time for this stream to live
///
internal void UpdateLifetime() {
int timeout = ServicePoint.ConnectionLeaseTimeout;
TimeSpan connectionLifetime;
if (timeout == System.Threading.Timeout.Infinite) {
connectionLifetime = TimeSpan.MaxValue;
m_CheckLifetime = false;
} else {
connectionLifetime = new TimeSpan(0, 0, 0, 0, timeout);
m_CheckLifetime = true;
}
if (connectionLifetime != m_Lifetime) {
m_Lifetime = connectionLifetime;
}
}
internal void Destroy() {
m_Owner = null;
m_ConnectionIsDoomed = true;
this.Close(0);
}
internal void PrePush(object expectedOwner) {
lock (this) {
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null == expectedOwner) {
if (null != m_Owner && null != m_Owner.Target)
throw new InternalException(); // new unpooled object has an owner
} else {
if (null == m_Owner || m_Owner.Target != expectedOwner)
throw new InternalException(); // unpooled object has incorrect owner
}
m_PooledCount++;
if (1 != m_PooledCount)
throw new InternalException(); // pushing object onto stack a second time
if (null != m_Owner)
m_Owner.Target = null;
}
}
internal void PostPop (object newOwner) {
GlobalLog.Assert(!IsEmancipated, "Pooled object not in pool.");
GlobalLog.Assert(CanBePooled, "Pooled object is not poolable.");
lock (this) {
if (null == m_Owner)
m_Owner = new WeakReference(newOwner);
else {
if (null != m_Owner.Target)
throw new InternalException(); // pooled connection already has an owner!
m_Owner.Target = newOwner;
}
m_PooledCount--;
if (null != Pool) {
if (0 != m_PooledCount)
throw new InternalException(); // popping object off stack with multiple pooledCount
} else {
if (-1 != m_PooledCount)
throw new InternalException(); // popping object off stack with multiple pooledCount
}
}
}
///
/// True if we're using a TlsStream
///
protected bool UsingSecureStream {
get {
#if !FEATURE_PAL
return (m_NetworkStream is TlsStream);
#else
return false;
#endif // !FEATURE_PAL
}
}
///
/// Allows inherited objects to modify NetworkStream
///
internal NetworkStream NetworkStream {
get {
return m_NetworkStream;
}
set {
m_Initalizing = false;
m_NetworkStream = value;
}
}
///
/// Gives the socket for internal use.
///
protected Socket Socket {
get {
return m_NetworkStream.InternalSocket;
}
}
///
/// Indicates that data can be read from the stream.
///
public override bool CanRead {
get {
return m_NetworkStream.CanRead;
}
}
///
/// Indicates that the stream is seekable
///
public override bool CanSeek {
get {
return m_NetworkStream.CanSeek;
}
}
///
/// Indicates that the stream is writeable
///
public override bool CanWrite {
get {
return m_NetworkStream.CanWrite;
}
}
///
/// Indicates whether we can timeout
///
public override bool CanTimeout {
get {
return m_NetworkStream.CanTimeout;
}
}
///
/// Set/Get ReadTimeout
///
public override int ReadTimeout {
get {
return m_NetworkStream.ReadTimeout;
}
set {
m_NetworkStream.ReadTimeout = value;
}
}
///
/// Set/Get WriteTimeout
///
public override int WriteTimeout {
get {
return m_NetworkStream.WriteTimeout;
}
set {
m_NetworkStream.WriteTimeout = value;
}
}
///
/// Indicates that the stream is writeable
///
public override long Length {
get {
return m_NetworkStream.Length;
}
}
///
/// Gets or sets the position in the stream. Always throws .
///
public override long Position {
get {
return m_NetworkStream.Position;
}
set {
m_NetworkStream.Position = value;
}
}
/*
// Consider removing.
///
/// Indicates the avail bytes
///
public bool DataAvailable {
get {
return m_NetworkStream.DataAvailable;
}
}
*/
///
/// Seeks a specific position in the stream.
///
public override long Seek(long offset, SeekOrigin origin) {
return m_NetworkStream.Seek(offset, origin);
}
///
/// Reads data from the stream.
///
public override int Read(byte[] buffer, int offset, int size) {
int result = m_NetworkStream.Read(buffer, offset, size);
GlobalLog.Dump(buffer, offset, result);
return result;
}
///
/// Writes data to the stream.
///
public override void Write(byte[] buffer, int offset, int size) {
GlobalLog.Dump(buffer, offset, size);
m_NetworkStream.Write(buffer, offset, size);
}
///
/// Writes multiple buffers at once
///
internal void MultipleWrite(BufferOffsetSize[] buffers) {
#if TRAVE
for (int i = 0; i < buffers.Length; ++i)
{
GlobalLog.Dump(buffers[i].Buffer, buffers[i].Offset, buffers[i].Size);
}
#endif
m_NetworkStream.MultipleWrite(buffers);
}
///
///
/// Closes the stream, and then closes the underlying socket.
///
///
protected override void Dispose(bool disposing) {
try {
if (disposing)
CloseSocket();
}
finally {
base.Dispose(disposing);
}
}
internal void CloseSocket() {
Socket socket = m_AbortSocket;
Socket socket6 = m_AbortSocket6;
m_NetworkStream.Close();
if (socket != null) {
socket.Close();
}
if (socket6 != null) {
socket6.Close();
}
}
public void Close(int timeout) {
Socket socket = m_AbortSocket;
Socket socket6 = m_AbortSocket6;
m_NetworkStream.Close(timeout);
if (socket != null) {
socket.Close(timeout);
}
if (socket6 != null) {
socket6.Close(timeout);
}
}
///
///
/// Begins an asychronous read from a stream.
///
///
[HostProtection(ExternalThreading=true)]
public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
return m_NetworkStream.BeginRead(buffer, offset, size, callback, state);
}
internal virtual IAsyncResult UnsafeBeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state)
{
return m_NetworkStream.UnsafeBeginRead(buffer, offset, size, callback, state);
}
///
///
/// Handle the end of an asynchronous read.
///
///
public override int EndRead(IAsyncResult asyncResult) {
// only caller can recover the debug dump for the read result
return m_NetworkStream.EndRead(asyncResult);
}
///
///
/// Begins an asynchronous write to a stream.
///
///
[HostProtection(ExternalThreading=true)]
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
GlobalLog.Dump(buffer, offset, size);
return m_NetworkStream.BeginWrite(buffer, offset, size, callback, state);
}
internal virtual IAsyncResult UnsafeBeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) {
GlobalLog.Dump(buffer, offset, size);
return m_NetworkStream.UnsafeBeginWrite(buffer, offset, size, callback, state);
}
///
///
/// Handle the end of an asynchronous write.
///
///
public override void EndWrite(IAsyncResult asyncResult) {
m_NetworkStream.EndWrite(asyncResult);
}
///
///
/// Begins an asynchronous write to a stream.
///
///
[HostProtection(ExternalThreading=true)]
internal IAsyncResult BeginMultipleWrite(BufferOffsetSize[] buffers, AsyncCallback callback, object state) {
#if TRAVE
for (int i = 0; i < buffers.Length; ++i)
{
GlobalLog.Dump(buffers[i].Buffer, buffers[i].Offset, buffers[i].Size);
}
#endif
return m_NetworkStream.BeginMultipleWrite(buffers, callback, state);
}
/*
// Consider removing.
internal IAsyncResult UnsafeBeginMultipleWrite(BufferOffsetSize[] buffers, AsyncCallback callback, object state) {
#if TRAVE
for (int i = 0; i < buffers.Length; ++i)
{
GlobalLog.Dump(buffers[i].Buffer, buffers[i].Offset, buffers[i].Size);
}
#endif
return m_NetworkStream.UnsafeBeginMultipleWrite(buffers, callback, state);
}
*/
///
///
/// Handle the end of an asynchronous write.
///
///
internal void EndMultipleWrite(IAsyncResult asyncResult) {
m_NetworkStream.EndMultipleWrite(asyncResult);
}
///
///
/// Flushes data from the stream.
///
///
public override void Flush() {
m_NetworkStream.Flush();
}
///
/// Sets the length of the stream.
///
public override void SetLength(long value) {
m_NetworkStream.SetLength(value);
}
internal void SetSocketTimeoutOption(SocketShutdown mode, int timeout, bool silent) {
m_NetworkStream.SetSocketTimeoutOption(mode, timeout, silent);
}
internal bool Poll(int microSeconds, SelectMode mode) {
return m_NetworkStream.Poll(microSeconds, mode);
}
internal bool PollRead() {
return m_NetworkStream.PollRead();
}
}
} // System.Net
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlDataSourceNodeDescriptor.cs
- SerialStream.cs
- CssStyleCollection.cs
- PrefixQName.cs
- RootBrowserWindow.cs
- DataKey.cs
- EntityProviderServices.cs
- TypeFieldSchema.cs
- TreeNodeClickEventArgs.cs
- DefinitionUpdate.cs
- SecurityDescriptor.cs
- TreeNodeBindingCollection.cs
- EntityDataSourceReferenceGroup.cs
- MULTI_QI.cs
- SecondaryIndex.cs
- MediaContext.cs
- ExpressionBindingsDialog.cs
- SqlConnectionPoolProviderInfo.cs
- SQLDoubleStorage.cs
- HMAC.cs
- CompilerTypeWithParams.cs
- MetafileHeaderEmf.cs
- RowToFieldTransformer.cs
- DbConnectionPoolCounters.cs
- SqlUtil.cs
- TextParagraphView.cs
- PartBasedPackageProperties.cs
- SqlDataReader.cs
- InternalConfigEventArgs.cs
- ResourceReferenceExpression.cs
- RootBrowserWindowProxy.cs
- BaseDataBoundControl.cs
- TextTreeInsertUndoUnit.cs
- LinqDataSourceContextEventArgs.cs
- TextContainer.cs
- XmlRootAttribute.cs
- BitmapEffectGroup.cs
- TemplateInstanceAttribute.cs
- XmlSortKeyAccumulator.cs
- SolidBrush.cs
- CacheEntry.cs
- DrawingContextWalker.cs
- ProxyWebPartManager.cs
- TableCell.cs
- GridViewDeletedEventArgs.cs
- FindCriteria11.cs
- RowParagraph.cs
- ListComponentEditor.cs
- ThicknessAnimationBase.cs
- SqlConnection.cs
- SqlTopReducer.cs
- CompilerTypeWithParams.cs
- DecimalAnimation.cs
- ZoneMembershipCondition.cs
- ServiceThrottlingBehavior.cs
- ObjectDataSourceView.cs
- RelationshipSet.cs
- WorkflowMarkupSerializer.cs
- KnownBoxes.cs
- PrinterSettings.cs
- CardSpaceShim.cs
- GlyphingCache.cs
- BoundColumn.cs
- XPathException.cs
- ConfigurationCollectionAttribute.cs
- GenericWebPart.cs
- OutputScopeManager.cs
- ReachDocumentPageSerializer.cs
- ToolbarAUtomationPeer.cs
- ObjectAssociationEndMapping.cs
- X509CertificateValidator.cs
- MeasurementDCInfo.cs
- InputScopeNameConverter.cs
- DataMember.cs
- PropertyMapper.cs
- DisplayMemberTemplateSelector.cs
- TdsParserSessionPool.cs
- ListDesigner.cs
- LingerOption.cs
- ReachUIElementCollectionSerializer.cs
- WebPartConnectionsCancelVerb.cs
- Light.cs
- Preprocessor.cs
- DummyDataSource.cs
- GenericEnumerator.cs
- DrawingVisualDrawingContext.cs
- AuthStoreRoleProvider.cs
- XmlIterators.cs
- PreparingEnlistment.cs
- Gdiplus.cs
- Tokenizer.cs
- PublisherMembershipCondition.cs
- EntitySetBase.cs
- StreamGeometry.cs
- HtmlElementCollection.cs
- CharacterBufferReference.cs
- XmlDataSourceView.cs
- Suspend.cs
- PolyLineSegment.cs
- BlobPersonalizationState.cs