CPacket CPacketPool 类 头文件

  

//
// Packet.h
//
// Copyright (c) Shareaza Development Team, 2002-2005.
// This file is part of SHAREAZA (
www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

// CPacket represents a packet on a peer-to-peer network, and CPacketPool keeps lists of them
//
http://wiki.shareaza.com/static/Developers.Code.CPacket

// Make the compiler only include the lines here once, this is the same thing as pragma once
#if !defined(AFX_PACKET_H__3094C1CC_8AD2_49BD_BF10_EA639A9EAE6F__INCLUDED_)
#define AFX_PACKET_H__3094C1CC_8AD2_49BD_BF10_EA639A9EAE6F__INCLUDED_

// Only include the lines beneath this one once
#pragma once

// Reverses the order of 2 bytes, like "12" to "21" 将字节转化为逆序的,如0X12变成0X21
#define SWAP_SHORT(x) ( ( ( (x) & 0xFF00 ) >> 8 ) + ( ( (x) & 0x00FF ) << 8 ) )

// Reverses the order of 4 bytes, like "1234" to "4321"
#define SWAP_LONG(x) ( ( ( (x) & 0xFF000000 ) >> 24 ) + ( ( (x) & 0x00FF0000 ) >> 8 ) + ( ( (x) & 0x0000FF00 ) << 8 ) + ( ( (x) & 0x000000FF ) << 24 ) )

// Reverses the order of 8 bytes, like "12345678" to "87654321"
#define SWAP_64(x) ( ( SWAP_LONG( (x) & 0xFFFFFFFF ) << 32 ) | SWAP_LONG( (x) >> 32 ) )

// When the allocated block of memory needs to be bigger, make it 128 bytes bigger
#define PACKET_GROW 128

// Sizes of buffers that hold 128 ASCII and 128 wide characters so MultiByteToWideChar can convert short text quickly
#define PACKET_BUF_SCHAR 127
#define PACKET_BUF_WCHAR 127

// Shareaza's vendor code is "RAZA", here is that text in ASCII and wide characters
#define SHAREAZA_VENDOR_A VENDOR_CODE
#define SHAREAZA_VENDOR_T _T( VENDOR_CODE )

// Tell the compiler these classes exist, and it will find out more about them soon
class CBuffer;
class CNeighbour;

// A packet on a peer-to-peer network

class CPacket
{

protected:

 // Create a new CPacket object, and delete this one

 // Make a new CPacket object for the given protocol id, like Gnutella or eDonkey2000

 CPacket(PROTOCOLID nProtocol);
 
 // The destructor is virtual, meaning classes that inherit from CPacket
 
 //may replace it with their own destructor

 virtual ~CPacket();         
 

public:

 // The network this packet is on, like Gnutella or eDonkey2000
 
 PROTOCOLID m_nProtocol;

 // List pointer and reference count

 // Unused packets in the packet pool are linked together from m_pFree,
 
 //through each packet's m_pNext pointer
 
 CPacket* m_pNext;

    // The number of other objects that need this packet and point to it,
 
 //0 if everyone is done with it

 DWORD    m_nReference;

public:

 // Packet data

 // A pointer to memory we allocated to hold the bytes of the payload
 
 //of the packet, this is not a CBuffer object 注意这里的m_pBuffer仅仅是一个Char *
 
 BYTE* m_pBuffer;   

    // The size of the allocated block of memory that holds the payload

 //分配的长度,而m_nLength是有效数据的长度,肯定是小于m_nBuffer的

 DWORD m_nBuffer;  

 // The number of bytes of data we've written into the allocated block of memory

 //有效数据的长度

 DWORD m_nLength;   

 //当前访问到的数据的位置

 // What byte we are on, this position index is remembered
 
 //by the packet between calls to methods
 
 DWORD m_nPosition; 

 // True if the bytes of the packet are in big endian format, which is the default

 //packet默认是big endian的,

 BOOL  m_bBigEndian;

 // Set the position a given distance forwards from the start, or backwards from the end
 
 enum { seekStart, seekEnd };

protected:

 // Buffers that hold 128 ASCII and 128 wide characters,

 //used so MultiByteToWideChar can convert short text quickly

 //对小于127个字符的utf8格式的转化提供了一个缓冲数组,从而对短文本的处理更快
 
 static CHAR  m_szSCHAR[PACKET_BUF_SCHAR + 1];
 
 // Static means these are separate from all the CPacket objects this class will make
 
 static WCHAR m_szWCHAR[PACKET_BUF_WCHAR + 1];

public:

 // Reset this packet object to make it like it was when it came from the constructor
 
 virtual void Reset();

 // What is const = 0 (do)
 
 virtual void ToBuffer(CBuffer* pBuffer) const = 0;

public:

 // Packet position and length

 // Set the position the given distance from the given end

 //将当前文件指针移动到相对于nRelative的nPosition位置
 
 void Seek(DWORD nPosition, int nRelative = seekStart);

 // Shorten the packet to the given number of bytes

 void Shorten(DWORD nLength);            

 // Read and write ASCII text in the packet

 //对packet的ascii内容的读写
 
 // Read null terminated ASCII text at our position in the packet
 
 virtual CString ReadString(DWORD nMaximum = 0xFFFFFFFF);   
 
 // Write ASCII text and a null terminator into the end of the packet

 virtual void    WriteString(LPCTSTR pszString, BOOL bNull = TRUE);

 // String utility, not at all related to the packet

 // Takes a string, and determines how long it would be as ASCII text

 //返回一个string的ascii文本的长度

 virtual int GetStringLen(LPCTSTR pszString) const;

 // Read and write ASCII text in the packet, using the UTF8 code page

 // Read null terminated ASCII text at our position in the packet

 //将buffer转化为utf8编码widechar,返回结果CString

 virtual CString ReadStringUTF8(DWORD nMaximum = 0xFFFFFFFF);          
 
 // Write ASCII text and a null terminator into the end of the packet

 //将utf8编码的widechar字符串转化为ascii编码,写入到buffer中

 virtual void    WriteStringUTF8(LPCTSTR pszString, BOOL bNull = TRUE);

 // String utility, not at all related to the packet

 // Takes a string, and determines how long it would be as ASCII text converted UTF8

 //计算出如果将参数字符串转化为utf8编码后的长度

 virtual int GetStringLenUTF8(LPCTSTR pszString) const;

 // Data compression

 // Read compressed data from the packet, decompress it, and return it

 //将当前buffer中的内容解压缩,返回解压缩的结果
 
 LPBYTE ReadZLib(DWORD nLength, DWORD* pnOutput, DWORD nSuggest = 0);

 // Compress the given data and write it into the packet

 //将参数pData压缩,结果写入到当前buffer中

 void   WriteZLib(LPCVOID pData, DWORD nLength);

 // Insert data into the packet

 // Makes room at the given spot, and returns a pointer to it

 //在nOffset位置空出DLength长度的位置,返回可写入nLength长度的数据开始位置

 BYTE* WriteGetPointer(DWORD nLength, DWORD nOffset = 0xFFFFFFFF);
 

public:

 // Inheriting classes will override this to return text describing what type of packet this is
 
 virtual LPCTSTR GetType() const;

 // Encode the bytes of the packet into text

  // Express the bytes of the packet in base 13 with spaces, like "08 C0 12 AF"
 
 CString ToHex()   const;


 // Express the bytes of the packet as ASCII characters, like "abc..fgh.i",
 
    //spaces replace low characters

 CString ToASCII() const;

 // Inheriting classes will override this to (do)
 
 virtual void    Debug(LPCTSTR pszReason) const;

 // Gives this packet and related objects to each window in the tab bar for them to process it

 //将当前Packet传给所有的CPacketWnd窗口,调用Process方法处理
 
 void SmartDump(CNeighbour* pNeighbour, IN_ADDR* pUDP, BOOL bOutgoing) const;

public:

 // Compute the SHA hash of the bytes of the packet

 //计算出当前packet的SHA1 hash 编码
 
 virtual BOOL GetRazaHash(SHA1* pHash, DWORD nLength = 0xFFFFFFFF) const;

 // Does nothing (do)
 
 void RazaSign();
 
 BOOL RazaVerify() const;

public:

 // Get the length beyond our position in the packet

 //返回剩余的还未处理的数据的长度
 
 inline int GetRemaining()
 {
  // Return the number of bytes of packet data at and beyond our position in the packet
 
  return m_nLength - m_nPosition;
 }

 // Takes a pointer to a buffer, and the number of bytes we want written there
 // Copies this number of bytes from the packet, and moves the packet's position beyond them

 //从m_nPosition位置开始,读取nLength个数据到pData中

 inline void Read(LPVOID pData, int nLength)
 {
  // Make sure the requested length doesn't poke beyond the end of the packet

  if ( m_nPosition + nLength > m_nLength ) // 不能超过有效数据的最大长度
  {
   AfxThrowUserException();
  }

  // Copy memory from the packet to the given buffer

  CopyMemory(
   pData,                   // Destination is the given pointer
   m_pBuffer + m_nPosition, // Source is our position in the packet
   nLength );               // Size is the requested length

  // Move our position in the packet beyond the data we just copied out

  m_nPosition += nLength;
 }

 // Read the next byte in the packet, moving the position beyond it
 // Returns the byte

 //读取 m_nPosition位置的一个字节,同时m_nPosition增加1指向下一个字节

 inline BYTE ReadByte()
 {
  // Make sure the position isn't at the end or beyond it, where there is no byte to read
  
  if ( m_nPosition >= m_nLength )
  {
   AfxThrowUserException();
  }

  // Read one byte, return it, and move our position in this packet beyond it

  return m_pBuffer[ m_nPosition++ ];
 }

 // Get the next byte in the packet, not moving the position beyond it
 // Returns the byte

 //读取一个字节,m_nPosition不增加
 
 inline BYTE PeekByte()
 {
  // Make sure the position isn't at the end or beyond it, where there is no byte to read
  
  if ( m_nPosition >= m_nLength )
  {
   AfxThrowUserException();
  }

  // Read one byte, return it, but don't move our position in this packet beyond it

  return m_pBuffer[ m_nPosition ];
 }

 // Read the next 2 bytes in the packet, moving the position beyond them
 // Returns the bytes in a word, and assumes little endian order which we don't need to change
 
 //读取小字节序的short

 inline WORD ReadShortLE()
 {
  // Make sure there are at least 2 bytes of data at our position in the packet
  
  if ( m_nPosition + 2 > m_nLength )
  {
   AfxThrowUserException();
  }

  // Read the 2 bytes at the position, and move the position past them
  
  WORD nValue = *(WORD*)( m_pBuffer + m_nPosition ); // Look at the pointer as a 2 byte word
  
  m_nPosition += 2;                                  // Move the position beyond it

  // Return the 2 bytes in a word
  
  return nValue;
 }

 // Read the next 2 bytes in the packet, moving the position beyond them
 // Returns the bytes in a word, switching their order if the packet thinks its contents are in big endian order
 
 //读取一个4字节数据,考虑bigendian的情况

 inline WORD ReadShortBE()
 {
  // Make sure there are at least 2 bytes of data at our position in the packet
  
  if ( m_nPosition + 2 > m_nLength )
  {
   AfxThrowUserException();
  }

  // Read the 2 bytes at the position, move the position past them, and return them
  
  WORD nValue = *(WORD*)( m_pBuffer + m_nPosition ); // Look at the pointer as a 2 byte word
  
  m_nPosition += 2;                                  // Move the position beyond it

  // If the packet is in big endian, reverse the order of the 2 bytes before returning them in a word
  
  return m_bBigEndian ? SWAP_SHORT( nValue ) : nValue;
 }

 // Read the next 4 bytes in the packet, moving the position beyond them
 // Returns the bytes in a DWORD, and assumes little endian order which we don't need to change
 
 //读取little endian的一个4字节数据

 inline DWORD ReadLongLE()
 {
  // Make sure there are at least 4 bytes of data at our position in the packet
  
  if ( m_nPosition + 4 > m_nLength )
  {
   AfxThrowUserException();
  }

  // Read the 4 bytes at the position, and move the position past them
  
  DWORD nValue = *(DWORD*)( m_pBuffer + m_nPosition ); // Look at the pointer as a 4 byte DWORD
  
  m_nPosition += 4;                                    // Move the position beyond it

  // Return the 4 bytes in a DWORD

  return nValue;
 }

 // Read the next 4 bytes in the packet, moving the position beyond them
 // Returns the bytes in a DWORD, reversing their order if the packet thinks its contents are in big endian order
 
 //考虑bigendian的字节序

 inline DWORD ReadLongBE()
 {
  // Make sure there are at least 4 bytes of data at our position in the packet

  if ( m_nPosition + 4 > m_nLength )
  {
   AfxThrowUserException();
  }

  // Read the 4 bytes at the position, and move the position past them
  
  DWORD nValue = *(DWORD*)( m_pBuffer + m_nPosition ); // Look at the pointer as a 4 byte DWORD
  
  m_nPosition += 4;                                    // Move the position beyond it

  // If the packet is in big endian, reverse the order of the 4 bytes before returning them in a DWORD
  
  return m_bBigEndian ? SWAP_LONG( nValue ) : nValue;
 }

 // Read the next 8 bytes in the packet, moving the position beyond them
 // Returns the bytes in a QWORD, reversing their order if the packet thinks its contents are in big endian order
 
 //读取8个字节,如果是bigedian则转化为小字节序,否则不变,m_nPosition 位置读取的

 inline QWORD ReadInt64()
 {
  // Make sure there are at least 8 bytes of data at our position in the packet

  if ( m_nPosition + 8 > m_nLength )
  {
   AfxThrowUserException();
  }

  // Read the 8 bytes at the position, and move the position past them
  
  QWORD nValue = *(QWORD*)( m_pBuffer + m_nPosition ); // Look at the pointer as a 8 byte QWORD
  
  m_nPosition += 8;                                    // Move the position beyond it

  // If the packet is in big endian, reverse the order of the 8 bytes before returning them in a QWORD
  
  return m_bBigEndian ? SWAP_64( nValue ) : nValue;
 }

 // Takes a length of bytes we would like to add to the packet
 // Ensures the allocated block of memory is big enough for them, making it bigger if necessary
 
 //确保剩余的空间大于参数nLength,如果不够则创建足够的空间

 inline void Ensure(int nLength)
 {
  // If the buffer isn't big enough to hold that many more new bytes

  if ( m_nLength + nLength > m_nBuffer ) // 剩余的空间不够了
  {
   // Switch to a new bigger one,每次增加PACKET_GROW 个字节
   
   m_nBuffer += max( nLength, PACKET_GROW ); // Size the buffer larger by the requested amount, or the packet grow size of 128 bytes
   
   LPBYTE pNew = new BYTE[ m_nBuffer ];      // Allocate a new block of memory of that size
   
   CopyMemory( pNew, m_pBuffer, m_nLength ); // Copy the packet data from the old buffer to the new one
   
   if ( m_pBuffer )
   {
    delete [] m_pBuffer;     // If there is an old buffer, free it
   }

   m_pBuffer = pNew;                         // Point the packet object's member variable pointer at the new buffer
  }
 }

 // Takes a pointer to data and the number of bytes there
 // Adds them to the end of the buffer

 //在buffer中加入pData指向的数据,如果不够则分配新的空间

 inline void Write(LPCVOID pData, int nLength)
 {
  // If the allocated block of memory doesn't have enough extra space to hold the new data

  if ( m_nLength + nLength > m_nBuffer ) // 剩余的空间不够了
  {
   // Make it bigger 开拓足够的空间

   m_nBuffer += max( nLength, PACKET_GROW ); // Calculate the new size to be nLength or 128 bytes bigger
   
   LPBYTE pNew = new BYTE[ m_nBuffer ];      // Allocate a new buffer of that size
   
   CopyMemory( pNew, m_pBuffer, m_nLength ); // Copy the data from the old buffer to the new one
   
   if ( m_pBuffer )
   {
    delete [] m_pBuffer;     // Delete the old buffer
   }

   m_pBuffer = pNew;                         // Point m_pBuffer at the new, bigger buffer
  }

  // Add the given data to the end of the packet将新的数据加入到buffer中

  CopyMemory( m_pBuffer + m_nLength, pData, nLength ); // Copy the data into the end
  
  m_nLength += nLength;                                // Record that the new bytes are stored here
 }

 // Takes a byte
 // Writes it into the end of the packet

 //将参数nValue加入到m_pBuffer数组的末尾

 inline void WriteByte(BYTE nValue)
 {
  // Make sure there is room for the byte

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write it at the end of the packet, and record that it is there

  m_pBuffer[ m_nLength++ ] = nValue;
 }

 // Takes 2 bytes in a word
 // Writes them into the end of the packet, keeping them in the same order

 //在最后写入两个字节的数据nValue,这里是little-endian了

 inline void WriteShortLE(WORD nValue)
 {
  // Make sure there is room for the 2 bytes

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write the two bytes as a word at the end of the packet, and record that it is there

  *(WORD*)( m_pBuffer + m_nLength ) = nValue;

  m_nLength += sizeof(nValue);
 }

 // Takes 2 bytes in a word
 // Writes them into the end of the packet, reversing their order if the packet is in big endian order
 
 //BigEndian写入两个字节的数据nValue,m_bBigEndian为真则调整字节顺序

 inline void WriteShortBE(WORD nValue)
 {
  // Make sure there is room for the 2 bytes

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write the 2 bytes as a word at the end of the packet, and record that it is there

  *(WORD*)( m_pBuffer + m_nLength ) =
   m_bBigEndian ? SWAP_SHORT( nValue ) : nValue; // Reverse their order if necessary

  m_nLength += sizeof(nValue);
 }

 // Takes 4 bytes in a DWORD
 // Writes them into the end of the packet, keeping them in the same order

 //小字节序写入4个字节的nValue

 inline void WriteLongLE(DWORD nValue)
 {
  // Make sure there is room for the 4 bytes

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write the 4 bytes as a DWORD at the end of the packet, and record that it is there
  
  *(DWORD*)( m_pBuffer + m_nLength ) = nValue;
  
  m_nLength += sizeof(nValue);
 }

 // Takes 4 bytes in a DWORD
 // Writes them into the end of the packet, reversing their order if the packet is in big endian order
 
 //根据m_bBigEndian是否是字节序来写入数据

 inline void WriteLongBE(DWORD nValue)
 {
  // Make sure there is room for the 4 bytes

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write the 4 bytes as a DWORD at the end of the packet, and record that it is there
  
  *(DWORD*)( m_pBuffer + m_nLength ) =
   m_bBigEndian ? SWAP_LONG( nValue ) : nValue; // Reverse their order if necessary

  m_nLength += sizeof(nValue);
 }

 // Takes 8 bytes in a QWORD
 // Writes them into the end of the packet, reversing their order if the packet is in big endian order
 
 //写入8个字节的数据

 inline void WriteInt64(QWORD nValue)
 {
  // Make sure there is room for the 8 bytes

  if ( m_nLength + sizeof(nValue) > m_nBuffer )
  {
   Ensure( sizeof(nValue) );
  }

  // Write the 8 bytes as a QWORD at the end of the packet, and record that it is there
  
  *(QWORD*)( m_pBuffer + m_nLength ) =
   m_bBigEndian ? SWAP_64( nValue ) : nValue; // Reverse their order if necessary

  m_nLength += sizeof(nValue);
 }

public:

 // Have this packet object remember that one more thing is referencing it

 //使用当前packet的对象数目增加1

 inline void AddRef()
 {
  // Incriment the reference count stored in the object

  m_nReference++;
 }

 // Tell this packet object that one less thing needs it

 //使用当前packet的对象释放当前packet的引用

 inline void Release()
 {
  // Decrement the reference count, and if that makes it go to 0, delete the object

  if ( this != NULL && ! --m_nReference )
  {
   Delete(); // 如果引用是0了,则直接删除内存空间,delete由子类实现
  }
 }

 // Decrement the reference count of this packet, the packet it points to,
 
 //and so on down the linked list from here

 //将从当前packet开始的所有Packet,依次调用Release方法
 
 inline void ReleaseChain()
 {
  // Make sure this object exists

  if ( this == NULL )
  {
   return;
  }

  // Point pPacket at this packet, and loop until that pointer becomes null

  //将当前packet后面的所有packet,调用release方法
  
  for ( CPacket* pPacket = this ; pPacket ; )
  {
   // Decrement the reference count of this packet, and move to the next one
   
   CPacket* pNext = pPacket->m_pNext; // Save a pointer to the next packet
   
   pPacket->Release();                // Record that one fewer object needs this one, which might delete it
   
   pPacket = pNext;                   // Move pPacket to the next one
  }
 }

 // (do)

 virtual inline void Delete() = 0;

 // Let the CPacketPool class access the private members of this one

 friend class CPacketPool;
};

// Allocates and holds array of 256 packets so we can grab a packet to use it quickly

class CPacketPool
{

public:

 // Make a new packet pool, and delete one
 
 CPacketPool();

 // Virtual lets inheriting classes override this with their own custom destructor

 virtual ~CPacketPool();

protected:

 // Free packets ready to be used

 // A linked list of packets that are free and ready to be removed from the linked list and used

 //指向使用过的Packet 的链表
 
 CPacket* m_pFree;

 // The total number of free packets in the linked list

 //m_pFree空闲packet链表中空闲packet的数目

 DWORD    m_nFree;

protected:

 // Used to make sure only one thread can access this object at a time
 
 CCriticalSection m_pSection;

 // An array of pointers, each of which points to an array of 256 packets
 
 //包含了很多CPacket*,每个CPacket*指向256个Packet的链表

 /*

 为什么要创建变量m_pPools呢?

    m_pPools中的元素是这样的:管理了一大堆CPacket*,仅管理指向
 
 256个Packet的头指针,也就是说它只负责申请和释放

 CPacket * -> CPacket * ... 256 个

 CPacket * -> CPacket * ... 256 个

 CPacket * -> CPacket * ... 256 个

 同时上面的这些CPacket又都在CPacket* m_pFree空闲链表中,一旦分配后

 立即加入到m_pFree中。m_pFree是一个结果链表,取得时候直接从这个list

 中取头结点,释放的时候直接将释放的packet加入到free list的开头。

 最后释放的时候遍历m_pPools链表,依次FreePoolImpl每个pool就ok了

 每次申请256个,从而避免每次都要申请,加快了申请速度。

 如果仅仅使用m_pFree来管理的话,一旦CPacket被取走了,就无法释放了,

 因为m_pFree头结点指向了后面的节点,无法找到被取走的节点了,而

 不论被取走的CPacket节点在哪里,m_pPools可以随时监控,释放之

 */

 CPtrArray m_pPools;

protected:

 // Delete all the packet pools, and make a new one
 
 void Clear();   // Delete all the packet pools in this CPacketPool object

 // Create a new packet pool, which is an array that can hold 256 packets,
 
 //and add it to the list here

 void NewPool();

protected:

 // Methods inheriting classes impliment to allocate and free arrays of 256 packets

 // Allocate a new array of 256 packets
 
 virtual void NewPoolImpl(int nSize, CPacket*& pPool, int& nPitch) = 0;

 
 // Free an array of 256 packets

 virtual void FreePoolImpl(CPacket* pPool) = 0;

public:

 // Removes a packet from the linked list of free packets,
 
 //resets it, and adds a reference count

 // Returns a pointer to the new packet the caller can use
 
 //返回一个可用的空闲packet指针

 inline CPacket* New()
 {
  // Make sure this is the only thread accessing this CPacketPool object at this time
 
  m_pSection.Lock();

  // If there aren't any packet pools yet, make one

  //没有空闲链表了,申请256个packet,使用CPacket*指针指向

  //然后将这256个Packet加入到空闲packet链表中

  if ( m_nFree == 0 )
  {
   // Now, m_pFree will point to the last packet in that pool,
   
   //and the first packet will point to null
  
   NewPool();
  }

     //有空闲packet可用

  // Make sure this caused the count of packets to go up, it should go to 256

  ASSERT( m_nFree > 0 );        
  
  // Remove the last linked packet in the most recently added packet pool
  
  //from the linked list of free packets
  
  //从Free Packet链表中卸下一个来,空闲packet数目减少1

  CPacket* pPacket = m_pFree; // Point pPacket at the last packet in the newest pool
  
  m_pFree = m_pFree->m_pNext; // Move m_pFree to the second to last packet in the newest pool
  
  m_nFree--;                  // Record that there is one fewer packet linked together in all the packet pools here

  // We're done, let other threads stuck on a Lock line like that one above inside
  
  m_pSection.Unlock();

  // Prepare the packet for use 将packet清空
  
  pPacket->Reset();  // Clear the values of the packet we just unlinked from the list
  
  //将当前packet的记数增加1

  pPacket->AddRef(); // Record that an external object is referencing this packet

  // Return a pointer to the packet we just
  
  return pPacket;
 }

 // Takes a pointer to a packet
 // Links it back into the list of free packets we can grab to use quickly

 //将参数指定的释放的packet加入到空闲packet链表
 
 inline void Delete(CPacket* pPacket)
 {
  // Make sure the pointer points to a packet, and that packet doesn't still have a reference count
 
  ASSERT( pPacket != NULL );

  ASSERT( pPacket->m_nReference == 0 );//确保这个packet没有被引用了

  // Make sure this is the only thread accessing this CPacketPool object at this time

  m_pSection.Lock();

  // Link the given packet back into the list of free ones we can use later

  //将参数pPacket加入到Freelist的开头

  pPacket->m_pNext = m_pFree; // Link the given packet into the front of the free list

  m_pFree = pPacket;

  //Free packet的数目增加1

  m_nFree++;                  // Record one more packet is in the free list

  // We're done, let other threads stuck on a Lock line like that one above inside

  m_pSection.Unlock();
 }
};

// End the group of lines to only include once, pragma once doesn't require an endif at the bottom

#endif // !defined(AFX_PACKET_H__3094C1CC_8AD2_49BD_BF10_EA639A9EAE6F__INCLUDED_)
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值