ByteBufferPool.cs

  1. // ==++==
  2. // 
  3. //   
  4. //    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5. //   
  6. //    The use and distribution terms for this software are contained in the file
  7. //    named license.txt, which can be found in the root of this distribution.
  8. //    By using this software in any fashion, you are agreeing to be bound by the
  9. //    terms of this license.
  10. //   
  11. //    You must not remove this notice, or any other, from this software.
  12. //   
  13. // 
  14. // ==--==
  15. //==========================================================================
  16. //  File:       ByteBufferPool.cs
  17. //
  18. //  Summary:    Stream used for reading from a socket by remoting channels.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.Threading;
  23. namespace System.IO
  24. {
  25.     internal interface IByteBufferPool
  26.     {
  27.         byte[] GetBuffer();
  28.         void ReturnBuffer(byte[] buffer);
  29.     }
  30.     // This isn't actually a buffer pool. It always creates a new byte buffer.
  31.     internal class ByteBufferAllocator : IByteBufferPool
  32.     {
  33.         private int _bufferSize;
  34.         public ByteBufferAllocator(int bufferSize)
  35.         {
  36.             _bufferSize = bufferSize;
  37.         }
  38.         public byte[] GetBuffer()
  39.         {
  40.             return new byte[_bufferSize];
  41.         }
  42.         public void ReturnBuffer(byte[] buffer)
  43.         {
  44.         }
  45.         
  46.     } // ByteBufferAllocator
  47.     internal class ByteBufferPool : IByteBufferPool
  48.     {
  49.         private byte[][] _bufferPool = null;
  50.     
  51.         private int _current; // -1 for none
  52.         private int _last;
  53.         private int _max;     // maximum number of buffers to pool
  54.         private int _bufferSize;
  55.         private Object _controlCookie = "cookie object";
  56.         public ByteBufferPool(int maxBuffers, int bufferSize)
  57.         {
  58.             _max = maxBuffers;        
  59.             _bufferPool = new byte[_max][];
  60.             _bufferSize = bufferSize;
  61.             _current = -1;
  62.             _last = -1;
  63.         } // ByteBufferPool        
  64.         
  65.         public byte[] GetBuffer()
  66.         {
  67.             Object cookie = null;
  68.             try
  69.             {
  70.                 // If a ThreadAbortException gets thrown after the exchange,
  71.                 //   but before the result is assigned to cookie, then the
  72.                 //   control cookie is lost forever. However, the buffer pool
  73.                 //   will still function normally and return everybody a new
  74.                 //   buffer each time (that isn't very likely to happen,
  75.                 //   so we don't really care).
  76.                 cookie = Interlocked.Exchange(ref _controlCookie, null);
  77.                 if (cookie != null)
  78.                 {
  79.                     // we have the control cookie, so take a buffer
  80.                 
  81.                     if (_current == -1)
  82.                     {
  83.                         _controlCookie = cookie;
  84.                         // no pooled buffers available
  85.                         return new byte[_bufferSize];
  86.                     }
  87.                     else
  88.                     {
  89.                         // grab next available buffer
  90.                         byte[] buffer = _bufferPool[_current];
  91.                         _bufferPool[_current] = null;      
  92.                         // update "current" index
  93.                         if (_current == _last)
  94.                         {
  95.                             // this is the last free buffer
  96.                             _current = -1;
  97.                         }
  98.                         else
  99.                         {
  100.                             _current = (_current + 1) % _max;
  101.                         }
  102.     
  103.                         _controlCookie = cookie;
  104.                         return buffer;
  105.                     }              
  106.                 }
  107.                 else
  108.                 {
  109.                     // we don't have the control cookie, so just create a new buffer since
  110.                     //   there will probably be a lot of contention anyway.
  111.                     return new byte[_bufferSize];
  112.                 }            
  113.             } 
  114.             catch (ThreadAbortException)
  115.             {
  116.                 if (cookie != null)
  117.                 {
  118.                     // This should be rare, so just reset
  119.                     //   everything to the initial state.
  120.                     _current = -1;
  121.                     _last = -1;
  122.                     // restore cookie
  123.                     _controlCookie = cookie;
  124.                 }
  125.             
  126.                 throw;
  127.             }                            
  128.         } // GetBuffer
  129.         public void ReturnBuffer(byte[] buffer)
  130.         {
  131.             if (buffer == null)
  132.                 throw new ArgumentNullException("buffer");
  133.                 
  134.         
  135.             // The purpose of the buffer pool is to try to reduce the 
  136.             //   amount of garbage generated, so it doesn't matter  if
  137.             //   the buffer gets tossed out. Since we don't want to
  138.             //   take the perf hit of taking a lock, we only return
  139.             //   the buffer if we can grab the control cookie.
  140.             
  141.             Object cookie = null;
  142.             try
  143.             {
  144.                 // If a ThreadAbortException gets thrown after the exchange,
  145.                 //   but before the result is assigned to cookie, then the
  146.                 //   control cookie is lost forever. However, the buffer pool
  147.                 //   will still function normally and return everybody a new
  148.                 //   buffer each time (that isn't very likely to happen,
  149.                 //   so we don't really care).
  150.                 cookie = Interlocked.Exchange(ref _controlCookie, null);
  151.                 
  152.                 if (cookie != null)
  153.                 {
  154.                     if (_current == -1)
  155.                     {
  156.                         _bufferPool[0] = buffer;
  157.                         _current = 0;
  158.                         _last = 0;
  159.                     }
  160.                     else
  161.                     {
  162.                         int newLast = (_last + 1) % _max;
  163.                         if (newLast != _current)
  164.                         {
  165.                             // the pool isn't full so store this buffer
  166.                             _last = newLast;
  167.                             _bufferPool[_last] = buffer;
  168.                         }
  169.                     }
  170.                     _controlCookie = cookie;
  171.                 }            
  172.             }
  173.             catch (ThreadAbortException)
  174.             {
  175.                 if (cookie != null)
  176.                 {
  177.                     // This should be rare, so just reset
  178.                     //   everything to the initial state.
  179.                     _current = -1;
  180.                     _last = -1;
  181.                     // restore cookie
  182.                     _controlCookie = cookie;
  183.                 }
  184.                 throw;            
  185.             }
  186.         } // ReturnBuffer
  187.         
  188.     } // ByteBufferPool
  189. // namespace System.IO
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值