Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 31, 2008, 12:05:12 AM (16 years ago)
Author:
rgrieder
Message:

Properly took care of network::packet::Packet destruction. It depends very much whether the the data was allocated by ENet or by ourselves.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/network/packet/Packet.cc

    r1960 r2070  
    6161  data_=0;
    6262  enetPacket_=0;
     63  bDataENetAllocated_ = false;
    6364}
    6465
     
    7374  data_=data;
    7475  enetPacket_=0;
     76  bDataENetAllocated_ = false;
    7577}
    7678
     
    8688  }else
    8789    data_=0;
    88 }
    89 
     90  bDataENetAllocated_ = p.bDataENetAllocated_;
     91}
     92
     93/**
     94@brief
     95    Destroys a packet completely.
     96   
     97    That also means destroying the ENetPacket if one exists. There
     98*/
    9099Packet::~Packet(){
    91   if(enetPacket_){
    92     assert(enetPacket_->freeCallback==0);
     100  // Deallocate data_ memory if necessary.
     101  if (this->bDataENetAllocated_){
     102    // In this case ENet allocated data_ and will destroy it.
     103  }
     104  else if (this->data_) {
     105    // This destructor was probably called as a consequence to ENet executing our callback.
     106    // It simply serves us to be able to deallocate the packet content (data_) ourselves since
     107    // we have created it in the first place.
     108    delete[] this->data_;
     109  }
     110
     111  // Destroy the ENetPacket if necessary.
     112  // Note: For the case ENet used the callback to destroy the packet, we have already set
     113  // enetPacket_ to NULL to avoid destroying it again.
     114  if (this->enetPacket_){
     115    // enetPacket_->data gets destroyed too by ENet if it was allocated by it.
    93116    enet_packet_destroy(enetPacket_);
    94117  }
    95   if(data_)
    96     delete[] data_;
    97118}
    98119
     
    107128      return false;
    108129    }
     130    // We deliver ENet the data address so that it doesn't memcpy everything again.
     131    // --> We have to delete data_ ourselves!
    109132    enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
    110133    enetPacket_->freeCallback = &Packet::deletePacket;
    111 //     enetPacket_->freeCallback = &blub;
     134    // Add the packet to a global list so we can access it again once enet calls our
     135    // deletePacket method. We can of course only give a one argument function to the ENet C library.
    112136    packetMap_[enetPacket_] = this;
    113137  }
     
    127151  }
    128152#endif
    129   ENetPacket *temp = enetPacket_;
    130   enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
    131   network::Host::addPacket( temp, clientID_);
     153//  ENetPacket *temp = enetPacket_;
     154//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
     155  network::Host::addPacket( enetPacket_, clientID_);
    132156  return true;
    133157}
     
    170194      break;
    171195  }
     196
     197  // Data was created by ENet
     198  p->bDataENetAllocated_ = true;
     199
    172200  return p;
    173201}
    174202
    175 void Packet::deletePacket(ENetPacket *packet){
    176   assert(packetMap_[packet]);
    177   assert(packetMap_[packet]->enetPacket_==0);
    178   delete packetMap_[packet];
     203/**
     204@brief
     205    ENet calls this method whenever it wants to destroy a packet that contains
     206    data we allocated ourselves.
     207*/
     208void Packet::deletePacket(ENetPacket *enetPacket){
     209  // Get our Packet from a gloabal map with all Packets created in the send() method of Packet.
     210  std::map<ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket);
     211  assert(it != packetMap_.end());
     212  // Make sure we don't delete it again in the destructor
     213  it->second->enetPacket_ = 0;
     214  delete it->second;
     215  packetMap_.erase(it);
    179216}
    180217
Note: See TracChangeset for help on using the changeset viewer.