2012-08-06 17:00:38 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* libretroshare/src/gxs: rsgxnetservice.cc
|
|
|
|
*
|
|
|
|
* Access to rs network and synchronisation service implementation
|
|
|
|
*
|
|
|
|
* Copyright 2012-2012 by Christopher Evi-Parker
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License Version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
#include "rsgxsnetservice.h"
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#define NXS_NET_DEBUG
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing)
|
2012-07-14 13:59:54 -04:00
|
|
|
#define TRANSAC_TIMEOUT 5 // 5 seconds
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
|
|
|
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs)
|
2012-07-14 13:59:54 -04:00
|
|
|
: p3Config(servType), p3ThreadedService(servType),
|
2012-07-15 08:38:20 -04:00
|
|
|
mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0),
|
2012-08-28 17:11:54 -04:00
|
|
|
mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD), mSyncTs(0)
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
{
|
2012-07-12 16:18:58 -04:00
|
|
|
addSerialType(new RsNxsSerialiser(mServType));
|
2012-07-15 08:38:20 -04:00
|
|
|
mOwnId = mNetMgr->getOwnId();
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
RsGxsNetService::~RsGxsNetService()
|
|
|
|
{
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
int RsGxsNetService::tick(){
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// always check for new items arriving
|
|
|
|
// from peers
|
2012-06-07 16:43:12 -04:00
|
|
|
if(receivedItems())
|
|
|
|
recvNxsItemQueue();
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
uint32_t now = time(NULL);
|
2012-08-28 17:11:54 -04:00
|
|
|
uint32_t elapsed = mSYNC_PERIOD + mSyncTs;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
if((elapsed) < now)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
|
|
|
syncWithPeers();
|
2012-07-14 13:59:54 -04:00
|
|
|
mSyncTs = now;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::syncWithPeers()
|
|
|
|
{
|
|
|
|
|
|
|
|
std::set<std::string> peers;
|
|
|
|
mNetMgr->getOnlineList(peers);
|
|
|
|
|
|
|
|
std::set<std::string>::iterator sit = peers.begin();
|
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
// for now just grps
|
|
|
|
for(; sit != peers.end(); sit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
|
|
|
grp->clear();
|
|
|
|
grp->PeerId(*sit);
|
|
|
|
sendItem(grp);
|
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
sit = peers.begin();
|
|
|
|
// TODO msgs
|
|
|
|
for(; sit != peers.end(); sit++)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
std::set<std::string>::iterator sit_grp = mGroupSubscribedTo.begin();
|
|
|
|
|
|
|
|
for(; sit_grp != mGroupSubscribedTo.end(); sit_grp++)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
|
|
|
|
msg->clear();
|
|
|
|
msg->PeerId(*sit);
|
|
|
|
msg->grpId = *sit_grp;
|
|
|
|
sendItem(msg);
|
|
|
|
}
|
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
bool RsGxsNetService::loadList(std::list<RsItem*>& load)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsSerialiser *RsGxsNetService::setupSerialiser()
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
void RsGxsNetService::recvNxsItemQueue(){
|
|
|
|
|
|
|
|
RsItem *item ;
|
|
|
|
|
|
|
|
while(NULL != (item=recvItem()))
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
|
|
|
#endif
|
|
|
|
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
|
|
|
//
|
|
|
|
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
|
|
|
if(ni != NULL)
|
|
|
|
{
|
2012-07-12 16:18:58 -04:00
|
|
|
|
|
|
|
// a live transaction has a non zero value
|
2012-06-07 16:43:12 -04:00
|
|
|
if(ni->transactionNumber != 0){
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "recvNxsItemQueue()" << std::endl;
|
|
|
|
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
if(handleTransaction(ni))
|
2012-06-16 09:59:40 -04:00
|
|
|
continue ;
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(ni->PacketSubType())
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
case RS_PKT_SUBTYPE_NXS_SYNC_GRP: handleRecvSyncGroup (dynamic_cast<RsNxsSyncGrp*>(ni)) ; break ;
|
|
|
|
case RS_PKT_SUBTYPE_NXS_SYNC_MSG: handleRecvSyncMessage (dynamic_cast<RsNxsSyncMsg*>(ni)) ; break ;
|
2012-06-07 16:43:12 -04:00
|
|
|
default:
|
2012-06-11 17:56:23 -04:00
|
|
|
std::cerr << "Unhandled item subtype " << ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
delete item ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
bool RsGxsNetService::handleTransaction(RsNxsItem* item){
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* This attempts to handle a transaction
|
|
|
|
* It first checks if this transaction id already exists
|
2012-07-12 16:18:58 -04:00
|
|
|
* If it does then check this not a initiating transactions
|
2012-06-11 17:56:23 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
const std::string& peer = item->PeerId();
|
|
|
|
|
|
|
|
RsNxsTransac* transItem = dynamic_cast<RsNxsTransac*>(item);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// if this is a RsNxsTransac item process
|
2012-06-11 17:56:23 -04:00
|
|
|
if(transItem){
|
|
|
|
return locked_processTransac(transItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
// then this must be transaction content to be consumed
|
|
|
|
// first check peer exist for transaction
|
2012-07-12 16:18:58 -04:00
|
|
|
bool peerTransExists = mTransactions.find(peer) != mTransactions.end();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// then check transaction exists
|
|
|
|
|
|
|
|
bool transExists = false;
|
|
|
|
NxsTransaction* tr = NULL;
|
|
|
|
uint32_t transN = item->transactionNumber;
|
|
|
|
|
|
|
|
if(peerTransExists)
|
|
|
|
{
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
|
|
|
|
transExists = transMap.find(transN) != transMap.end();
|
|
|
|
|
|
|
|
if(transExists){
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "handleTransaction() " << std::endl;
|
|
|
|
std::cerr << "Consuming Transaction content, transN: " << item->transactionNumber << std::endl;
|
|
|
|
std::cerr << "Consuming Transaction content, from Peer: " << item->PeerId() << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
tr = transMap[transN];
|
|
|
|
tr->mItems.push_back(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
|
|
|
|
{
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
/*!
|
|
|
|
* To process the transaction item
|
|
|
|
* It can either be initiating a transaction
|
|
|
|
* or ending one that already exists
|
|
|
|
*
|
|
|
|
* For initiating an incoming transaction the peer
|
|
|
|
* and transaction item need not exists
|
|
|
|
* as the peer will be added and transaction number
|
|
|
|
* added thereafter
|
|
|
|
*
|
|
|
|
* For commencing/starting an outgoing transaction
|
|
|
|
* the transaction must exist already
|
|
|
|
*
|
|
|
|
* For ending a transaction the
|
|
|
|
*/
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
std::string peer;
|
|
|
|
|
|
|
|
// for outgoing transaction use own id
|
|
|
|
if(item->transactFlag & (RsNxsTransac::FLAG_BEGIN_P2 | RsNxsTransac::FLAG_END_SUCCESS))
|
|
|
|
peer = mOwnId;
|
|
|
|
else
|
|
|
|
peer = item->PeerId();
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
uint32_t transN = item->transactionNumber;
|
2012-07-14 13:59:54 -04:00
|
|
|
item->timestamp = time(NULL); // register time received
|
2012-06-11 17:56:23 -04:00
|
|
|
NxsTransaction* tr = NULL;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_processTransac() " << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), Received transaction item: " << transN << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), With peer: " << item->PeerId() << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), trans type: " << item->transactFlag << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
bool peerTrExists = mTransactions.find(peer) != mTransactions.end();
|
|
|
|
bool transExists = false;
|
|
|
|
|
|
|
|
if(peerTrExists){
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
2012-07-12 16:18:58 -04:00
|
|
|
// record whether transaction exists already
|
2012-06-11 17:56:23 -04:00
|
|
|
transExists = transMap.find(transN) != transMap.end();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// initiating an incoming transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
if(item->transactFlag & RsNxsTransac::FLAG_BEGIN_P1){
|
|
|
|
|
|
|
|
// create a transaction if the peer does not exist
|
|
|
|
if(!peerTrExists){
|
|
|
|
mTransactions[peer] = TransactionIdMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
|
|
|
|
if(transExists)
|
2012-07-15 08:38:20 -04:00
|
|
|
return false; // should not happen!
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// create new transaction
|
|
|
|
tr = new NxsTransaction();
|
|
|
|
transMap[transN] = tr;
|
|
|
|
tr->mTransaction = item;
|
2012-07-15 08:38:20 -04:00
|
|
|
tr->mTimeOut = item->timestamp + mTransactionTimeOut;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// note state as receiving, commencement item
|
|
|
|
// is sent on next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_STARTING;
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// commencement item for outgoing transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}else if(item->transactFlag & RsNxsTransac::FLAG_BEGIN_P2){
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
// transaction must exist
|
2012-06-16 09:59:40 -04:00
|
|
|
if(!peerTrExists || !transExists)
|
2012-06-11 17:56:23 -04:00
|
|
|
return false;
|
2012-06-16 09:59:40 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// alter state so transaction content is sent on
|
|
|
|
// next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
TransactionIdMap& transMap = mTransactions[mOwnId];
|
|
|
|
NxsTransaction* tr = transMap[transN];
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_SENDING;
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// end transac item for outgoing transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}else if(item->transactFlag & RsNxsTransac::FLAG_END_SUCCESS){
|
|
|
|
|
2012-06-16 09:59:40 -04:00
|
|
|
// transaction does not exist
|
2012-06-11 17:56:23 -04:00
|
|
|
if(!peerTrExists || !transExists){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// alter state so that transaction is removed
|
|
|
|
// on next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
TransactionIdMap& transMap = mTransactions[mOwnId];
|
|
|
|
NxsTransaction* tr = transMap[transN];
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED;
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
return true;
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::run(){
|
|
|
|
|
|
|
|
|
|
|
|
double timeDelta = 0.2;
|
|
|
|
|
|
|
|
while(isRunning()){
|
|
|
|
|
|
|
|
#ifndef WINDOWS_SYS
|
|
|
|
usleep((int) (timeDelta * 1000000));
|
|
|
|
#else
|
|
|
|
Sleep((int) (timeDelta * 1000));
|
|
|
|
#endif
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// process active transactions
|
2012-06-07 16:43:12 -04:00
|
|
|
processTransactions();
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// process completed transactions
|
2012-06-11 17:56:23 -04:00
|
|
|
processCompletedTransactions();
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
2012-09-01 10:47:22 -04:00
|
|
|
return tr->mTimeOut < ((uint32_t) time(NULL));
|
|
|
|
// return false;
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
void RsGxsNetService::processTransactions(){
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
TransactionsPeerMap::iterator mit = mTransactions.begin();
|
|
|
|
|
|
|
|
for(; mit != mTransactions.end(); mit++){
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mit->second;
|
|
|
|
TransactionIdMap::iterator mmit = transMap.begin(),
|
|
|
|
|
|
|
|
mmit_end = transMap.end();
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
/*!
|
|
|
|
* Transactions owned by peer
|
|
|
|
*/
|
2012-06-11 17:56:23 -04:00
|
|
|
if(mit->first == mOwnId){
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// transaction to be removed
|
2012-06-11 17:56:23 -04:00
|
|
|
std::list<uint32_t> toRemove;
|
|
|
|
|
|
|
|
for(; mmit != mmit_end; mmit++){
|
|
|
|
|
|
|
|
NxsTransaction* tr = mmit->second;
|
|
|
|
uint16_t flag = tr->mFlag;
|
|
|
|
std::list<RsNxsItem*>::iterator lit, lit_end;
|
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// first check transaction has not expired
|
2012-07-15 08:38:20 -04:00
|
|
|
if(locked_checkTransacTimedOut(tr))
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "Transaction has failed, tranN: " << transN << std::endl;
|
|
|
|
std::cerr << "Transaction has failed, Peer: " << mit->first << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
toRemove.push_back(transN);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
// send items requested
|
|
|
|
if(flag & NxsTransaction::FLAG_STATE_SENDING){
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "Sending Transaction content, transN: " << transN << std::endl;
|
|
|
|
std::cerr << "with peer: " << tr->mTransaction->PeerId();
|
|
|
|
#endif
|
2012-06-11 17:56:23 -04:00
|
|
|
lit = tr->mItems.begin();
|
|
|
|
lit_end = tr->mItems.end();
|
|
|
|
|
|
|
|
for(; lit != lit_end; lit++){
|
|
|
|
sendItem(*lit);
|
|
|
|
}
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
tr->mItems.clear(); // clear so they don't get deleted in trans cleaning
|
2012-06-11 17:56:23 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_WAITING_CONFIRM){
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
|
|
|
|
// move to completed transactions
|
|
|
|
toRemove.push_back(transN);
|
|
|
|
mComplTransactions.push_back(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}else{
|
|
|
|
|
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag for active transaction, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag, Peer: " << mit->first;
|
|
|
|
toRemove.push_back(transN);
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
mComplTransactions.push_back(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::list<uint32_t>::iterator lit = toRemove.begin();
|
|
|
|
|
|
|
|
for(; lit != toRemove.end(); lit++)
|
|
|
|
{
|
|
|
|
transMap.erase(*lit);
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Essentially these are incoming transactions
|
|
|
|
* Several states are dealth with
|
|
|
|
* Receiving: waiting to receive items from peer's transaction
|
|
|
|
* and checking if all have been received
|
|
|
|
* Completed: remove transaction from active and tell peer
|
|
|
|
* involved in transaction
|
|
|
|
* Starting: this is a new transaction and need to teell peer
|
|
|
|
* involved in transaction
|
|
|
|
*/
|
|
|
|
|
|
|
|
std::list<uint32_t> toRemove;
|
|
|
|
|
|
|
|
for(; mmit != mmit_end; mmit++){
|
|
|
|
|
|
|
|
NxsTransaction* tr = mmit->second;
|
|
|
|
uint16_t flag = tr->mFlag;
|
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// first check transaction has not expired
|
2012-07-15 08:38:20 -04:00
|
|
|
if(locked_checkTransacTimedOut(tr))
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "Transaction has failed, tranN: " << transN << std::endl;
|
|
|
|
std::cerr << "Transaction has failed, Peer: " << mit->first << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
toRemove.push_back(transN);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
if(flag & NxsTransaction::FLAG_STATE_RECEIVING){
|
2012-07-12 16:18:58 -04:00
|
|
|
|
|
|
|
// if the number it item received equal that indicated
|
|
|
|
// then transaction is marked as completed
|
|
|
|
// to be moved to complete transations
|
2012-06-11 17:56:23 -04:00
|
|
|
// check if done
|
|
|
|
if(tr->mItems.size() == tr->mTransaction->nItems)
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_COMPLETED)
|
|
|
|
{
|
|
|
|
|
|
|
|
// send completion msg
|
|
|
|
RsNxsTransac* trans = new RsNxsTransac(mServType);
|
|
|
|
trans->clear();
|
|
|
|
trans->transactFlag = RsNxsTransac::FLAG_END_SUCCESS;
|
|
|
|
trans->transactionNumber = transN;
|
|
|
|
trans->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(trans);
|
|
|
|
|
|
|
|
// move to completed transactions
|
|
|
|
mComplTransactions.push_back(tr);
|
|
|
|
|
|
|
|
// transaction processing done
|
|
|
|
// for this id, add to removal list
|
|
|
|
toRemove.push_back(mmit->first);
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_STARTING){
|
|
|
|
|
|
|
|
// send item to tell peer your are ready to start
|
|
|
|
RsNxsTransac* trans = new RsNxsTransac(mServType);
|
|
|
|
trans->clear();
|
2012-07-14 13:59:54 -04:00
|
|
|
trans->transactFlag = RsNxsTransac::FLAG_BEGIN_P2 |
|
|
|
|
(tr->mTransaction->transactFlag & RsNxsTransac::FLAG_TYPE_MASK);
|
2012-06-11 17:56:23 -04:00
|
|
|
trans->transactionNumber = transN;
|
|
|
|
trans->PeerId(tr->mTransaction->PeerId());
|
2012-07-14 13:59:54 -04:00
|
|
|
sendItem(trans);
|
2012-07-15 08:38:20 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_RECEIVING;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag for active transaction, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag, Peer: " << mit->first;
|
|
|
|
toRemove.push_back(mmit->first);
|
|
|
|
mComplTransactions.push_back(tr);
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; // flag as a failed transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::list<uint32_t>::iterator lit = toRemove.begin();
|
|
|
|
|
|
|
|
for(; lit != toRemove.end(); lit++)
|
|
|
|
{
|
|
|
|
transMap.erase(*lit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::processCompletedTransactions()
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-06-11 17:56:23 -04:00
|
|
|
/*!
|
|
|
|
* Depending on transaction we may have to respond to peer
|
|
|
|
* responsible for transaction
|
|
|
|
*/
|
|
|
|
std::list<NxsTransaction*>::iterator lit = mComplTransactions.begin();
|
|
|
|
|
|
|
|
while(mComplTransactions.size()>0)
|
|
|
|
{
|
|
|
|
|
|
|
|
NxsTransaction* tr = mComplTransactions.front();
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
bool outgoing = tr->mTransaction->PeerId() == mOwnId;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
if(outgoing){
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_processCompletedOutgoingTrans(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}else{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_processCompletedIncomingTrans(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
delete tr;
|
|
|
|
mComplTransactions.pop_front();
|
|
|
|
}
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
uint16_t flag = tr->mTransaction->transactFlag;
|
|
|
|
|
|
|
|
if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
// for a completed list response transaction
|
|
|
|
// one needs generate requests from this
|
|
|
|
if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP)
|
|
|
|
{
|
|
|
|
// generate request based on a peers response
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genReqMsgTransaction(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genReqGrpTransaction(tr);
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
// you've finished receiving request information now gen
|
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genSendMsgsTransaction(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ)
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genSendGrpsTransaction(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_GRPS)
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
std::vector<RsNxsGrp*> grps;
|
|
|
|
|
|
|
|
while(tr->mItems.size() != 0)
|
|
|
|
{
|
|
|
|
RsNxsGrp* grp = dynamic_cast<RsNxsGrp*>(tr->mItems.front());
|
|
|
|
|
|
|
|
if(grp)
|
|
|
|
{
|
|
|
|
tr->mItems.pop_front();
|
|
|
|
grps.push_back(grp);
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
//TODO: remove subscription should be handled
|
|
|
|
// outside netservice
|
|
|
|
mGroupSubscribedTo.insert(grp->grpId);
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to grp"
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// notify listener of grps
|
|
|
|
mObserver->notifyNewGroups(grps);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
std::vector<RsNxsMsg*> msgs;
|
|
|
|
|
|
|
|
while(tr->mItems.size() > 0)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front());
|
|
|
|
if(msg)
|
|
|
|
{
|
|
|
|
tr->mItems.pop_front();
|
|
|
|
msgs.push_back(msg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
int nitems = msgs.size();
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// notify listener of msgs
|
|
|
|
mObserver->notifyNewMessages(msgs);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
|
|
|
|
// don't do anything transaction will simply be cleaned
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
uint16_t flag = tr->mTransaction->transactFlag;
|
|
|
|
|
|
|
|
if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
// for a completed list response transaction
|
|
|
|
// one needs generate requests from this
|
|
|
|
if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2012-07-14 13:59:54 -04:00
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg List Response, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Grp Response, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
2012-06-11 17:56:23 -04:00
|
|
|
#endif
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
// you've finished sending a request so don't do anything
|
|
|
|
else if( (flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ) ||
|
|
|
|
(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ) )
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg/Grp Request, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRPS)
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Grp Data, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg Data, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "Failed transaction! transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}else{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "Serious error unrecognised trans Flag! transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
2012-06-11 17:56:23 -04:00
|
|
|
{
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
// to create a transaction you need to know who you are transacting with
|
|
|
|
// then what msgs to request
|
|
|
|
// then add an active Transaction for request
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
std::list<RsNxsSyncMsgItem*> msgItemL;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-26 15:52:01 -04:00
|
|
|
// first get item list sent from transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
msgItemL.push_back(item);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
2012-06-26 15:52:01 -04:00
|
|
|
std::cerr << "RsGxsNetService::genReqMsgTransaction(): item failed cast to RsNxsSyncMsgItem* "
|
2012-06-11 17:56:23 -04:00
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
delete item;
|
|
|
|
item = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// get grp id for this transaction
|
|
|
|
RsNxsSyncMsgItem* item = msgItemL.front();
|
|
|
|
const std::string& grpId = item->grpId;
|
2012-09-01 10:47:22 -04:00
|
|
|
GxsMsgReq reqIds;
|
|
|
|
reqIds[grpId] = std::vector<RsGxsMessageId>();
|
2012-07-14 13:59:54 -04:00
|
|
|
GxsMsgMetaResult result;
|
2012-09-01 10:47:22 -04:00
|
|
|
mDataStore->retrieveGxsMsgMetaData(reqIds, result);
|
2012-07-14 13:59:54 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*> &msgMetaV = result[grpId];
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>::const_iterator vit = msgMetaV.begin();
|
|
|
|
std::set<std::string> msgIdSet;
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// put ids in set for each searching
|
|
|
|
for(; vit != msgMetaV.end(); vit++)
|
|
|
|
msgIdSet.insert((*vit)->mMsgId);
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// get unique id for this transaction
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// add msgs that you don't have to request list
|
|
|
|
std::list<RsNxsSyncMsgItem*>::iterator llit = msgItemL.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
const std::string peerFrom = tr->mTransaction->PeerId();
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
for(; llit != msgItemL.end(); llit++)
|
|
|
|
{
|
|
|
|
const std::string& msgId = (*llit)->msgId;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
if(msgIdSet.find(msgId) == msgIdSet.end()){
|
2012-06-11 17:56:23 -04:00
|
|
|
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
|
|
|
|
msgItem->grpId = grpId;
|
|
|
|
msgItem->msgId = msgId;
|
|
|
|
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
msgItem->transactionNumber = transN;
|
2012-09-01 10:47:22 -04:00
|
|
|
msgItem->PeerId(peerFrom);
|
2012-06-11 17:56:23 -04:00
|
|
|
reqList.push_back(msgItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
if(!reqList.empty())
|
2012-08-28 17:11:54 -04:00
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
RsNxsTransac* transac = new RsNxsTransac(mServType);
|
|
|
|
transac->transactFlag = RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ
|
|
|
|
| RsNxsTransac::FLAG_BEGIN_P1;
|
|
|
|
transac->timestamp = 0;
|
|
|
|
transac->nItems = reqList.size();
|
|
|
|
transac->PeerId(tr->mTransaction->PeerId());
|
|
|
|
transac->transactionNumber = transN;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
NxsTransaction* newTrans = new NxsTransaction();
|
|
|
|
newTrans->mItems = reqList;
|
|
|
|
newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
// create transaction copy with your id to indicate
|
|
|
|
// its an outgoing transaction
|
|
|
|
newTrans->mTransaction = new RsNxsTransac(*transac);
|
|
|
|
newTrans->mTransaction->PeerId(mOwnId);
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
sendItem(transac);
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
{
|
|
|
|
if(!locked_addTransaction(newTrans))
|
|
|
|
delete newTrans;
|
|
|
|
}
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
|
2012-06-11 17:56:23 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
// to create a transaction you need to know who you are transacting with
|
|
|
|
// then what grps to request
|
|
|
|
// then add an active Transaction for request
|
|
|
|
|
|
|
|
std::list<RsNxsSyncGrpItem*> grpItemL;
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* item = dynamic_cast<RsNxsSyncGrpItem*>(*lit);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
grpItemL.push_back(item);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::genReqMsgTransaction(): item failed to caste to RsNxsSyncMsgItem* "
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
delete item;
|
|
|
|
item = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::map<std::string, RsGxsGrpMetaData*> grpMetaMap;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// now do compare and add loop
|
|
|
|
std::list<RsNxsSyncGrpItem*>::iterator llit = grpItemL.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
for(; llit != grpItemL.end(); llit++)
|
|
|
|
{
|
|
|
|
const std::string& grpId = (*llit)->grpId;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
if(grpMetaMap.find(grpId) == grpMetaMap.end()){
|
2012-06-11 17:56:23 -04:00
|
|
|
RsNxsSyncGrpItem* grpItem = new RsNxsSyncGrpItem(mServType);
|
2012-08-28 17:11:54 -04:00
|
|
|
grpItem->PeerId(tr->mTransaction->PeerId());
|
2012-06-11 17:56:23 -04:00
|
|
|
grpItem->grpId = grpId;
|
|
|
|
grpItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
grpItem->transactionNumber = transN;
|
|
|
|
reqList.push_back(grpItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
if(!reqList.empty())
|
|
|
|
{
|
|
|
|
|
|
|
|
RsNxsTransac* transac = new RsNxsTransac(mServType);
|
|
|
|
transac->transactFlag = RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ
|
|
|
|
| RsNxsTransac::FLAG_BEGIN_P1;
|
|
|
|
transac->timestamp = 0;
|
|
|
|
transac->nItems = reqList.size();
|
|
|
|
transac->PeerId(tr->mTransaction->PeerId());
|
|
|
|
transac->transactionNumber = transN;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
NxsTransaction* newTrans = new NxsTransaction();
|
|
|
|
newTrans->mItems = reqList;
|
|
|
|
newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
|
|
|
|
newTrans->mTransaction = new RsNxsTransac(*transac);
|
|
|
|
newTrans->mTransaction->PeerId(mOwnId);
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
sendItem(transac);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
if(!locked_addTransaction(newTrans))
|
|
|
|
delete newTrans;
|
2012-07-15 08:38:20 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// clean up meta data
|
|
|
|
std::map<std::string, RsGxsGrpMetaData*>::iterator mit = grpMetaMap.begin();
|
|
|
|
|
|
|
|
for(; mit != grpMetaMap.end(); mit++)
|
|
|
|
delete mit->second;
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_genSendGrpsTransaction()" << std::endl;
|
|
|
|
std::cerr << "Generating Grp data send fron TransN: " << tr->mTransaction->transactionNumber
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// go groups requested in transaction tr
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
std::map<std::string, RsNxsGrp*> grps;
|
|
|
|
|
|
|
|
for(;lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* item = dynamic_cast<RsNxsSyncGrpItem*>(*lit);
|
|
|
|
grps[item->grpId] = NULL;
|
|
|
|
}
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
if(!grps.empty())
|
|
|
|
{
|
|
|
|
mDataStore->retrieveNxsGrps(grps, false, false);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
return;
|
|
|
|
}
|
2012-07-15 08:38:20 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
NxsTransaction* newTr = new NxsTransaction();
|
|
|
|
newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// store grp items to send in transaction
|
|
|
|
std::map<std::string, RsNxsGrp*>::iterator mit = grps.begin();
|
2012-07-15 08:38:20 -04:00
|
|
|
std::string peerId = tr->mTransaction->PeerId();
|
2012-07-14 13:59:54 -04:00
|
|
|
for(;mit != grps.end(); mit++)
|
|
|
|
{
|
2012-09-01 10:47:22 -04:00
|
|
|
mit->second->PeerId(peerId); // set so it gets sent to right peer
|
2012-07-15 08:38:20 -04:00
|
|
|
mit->second->transactionNumber = transN;
|
2012-07-14 13:59:54 -04:00
|
|
|
newTr->mItems.push_back(mit->second);
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
if(newTr->mItems.empty()){
|
|
|
|
delete newTr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
RsNxsTransac* ntr = new RsNxsTransac(mServType);
|
2012-07-15 08:38:20 -04:00
|
|
|
ntr->transactionNumber = transN;
|
2012-07-14 13:59:54 -04:00
|
|
|
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
|
|
|
|
RsNxsTransac::FLAG_TYPE_GRPS;
|
|
|
|
ntr->nItems = grps.size();
|
2012-08-28 17:11:54 -04:00
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
newTr->mTransaction = new RsNxsTransac(*ntr);
|
|
|
|
newTr->mTransaction->PeerId(mOwnId);
|
2012-07-15 08:38:20 -04:00
|
|
|
newTr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(ntr);
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_addTransaction(newTr);
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_genSendMsgsTransaction()" << std::endl;
|
|
|
|
std::cerr << "Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// go groups requested in transaction tr
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
GxsMsgReq msgIds;
|
|
|
|
GxsMsgResult msgs;
|
|
|
|
|
|
|
|
if(tr->mItems.empty()){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(;lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
|
|
|
|
msgIds[item->grpId].push_back(item->msgId);
|
|
|
|
}
|
|
|
|
|
|
|
|
mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false);
|
|
|
|
|
|
|
|
NxsTransaction* newTr = new NxsTransaction();
|
|
|
|
newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
|
|
|
// store grp items to send in transaction
|
|
|
|
GxsMsgResult::iterator mit = msgs.begin();
|
|
|
|
std::string peerId = tr->mTransaction->PeerId();
|
|
|
|
uint32_t msgSize = 0;
|
|
|
|
|
|
|
|
for(;mit != msgs.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsNxsMsg*>& msgV = mit->second;
|
|
|
|
std::vector<RsNxsMsg*>::iterator vit = msgV.begin();
|
|
|
|
|
|
|
|
for(; vit != msgV.end(); vit++)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *vit;
|
|
|
|
msg->PeerId(peerId);
|
|
|
|
msg->transactionNumber = transN;
|
|
|
|
newTr->mItems.push_back(msg);
|
|
|
|
msgSize++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(newTr->mItems.empty()){
|
|
|
|
delete newTr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsTransac* ntr = new RsNxsTransac(mServType);
|
|
|
|
ntr->transactionNumber = transN;
|
|
|
|
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
|
|
|
|
RsNxsTransac::FLAG_TYPE_MSGS;
|
|
|
|
ntr->nItems = msgSize;
|
|
|
|
ntr->PeerId(peerId);
|
|
|
|
|
|
|
|
newTr->mTransaction = new RsNxsTransac(*ntr);
|
|
|
|
newTr->mTransaction->PeerId(mOwnId);
|
|
|
|
newTr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
|
|
|
|
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(ntr);
|
|
|
|
|
|
|
|
locked_addTransaction(newTr);
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t RsGxsNetService::locked_getTransactionId()
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
return ++mTransactionN;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr)
|
|
|
|
{
|
|
|
|
const std::string& peer = tr->mTransaction->PeerId();
|
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
bool transNumExist = transMap.find(transN)
|
|
|
|
!= transMap.end();
|
|
|
|
|
|
|
|
|
|
|
|
if(transNumExist){
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_addTransaction() " << std::endl;
|
|
|
|
std::cerr << "Transaction number exist already, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
2012-06-11 17:56:23 -04:00
|
|
|
return false;
|
|
|
|
}else{
|
|
|
|
transMap[transN] = tr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::cleanTransactionItems(NxsTransaction* tr) const
|
|
|
|
{
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
delete *lit;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr->mItems.clear();
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
|
|
|
|
{
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
std::string peer = item->PeerId();
|
|
|
|
|
|
|
|
std::map<std::string, RsGxsGrpMetaData*> grp;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grp);
|
|
|
|
|
|
|
|
if(grp.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::map<std::string, RsGxsGrpMetaData*>::iterator mit =
|
|
|
|
grp.begin();
|
|
|
|
|
|
|
|
NxsTransaction* tr = new NxsTransaction();
|
|
|
|
std::list<RsNxsItem*>& itemL = tr->mItems;
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
for(; mit != grp.end(); mit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* gItem = new
|
|
|
|
RsNxsSyncGrpItem(mServType);
|
|
|
|
gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
gItem->grpId = mit->first;
|
|
|
|
gItem->publishTs = mit->second->mPublishTs;
|
|
|
|
gItem->PeerId(peer);
|
2012-07-15 08:38:20 -04:00
|
|
|
gItem->transactionNumber = transN;
|
2012-07-12 16:18:58 -04:00
|
|
|
itemL.push_back(gItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
RsNxsTransac* trItem = new RsNxsTransac(mServType);
|
|
|
|
trItem->transactFlag = RsNxsTransac::FLAG_BEGIN_P1
|
|
|
|
| RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP;
|
|
|
|
trItem->nItems = itemL.size();
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
trItem->timestamp = 0;
|
2012-07-12 16:18:58 -04:00
|
|
|
trItem->PeerId(peer);
|
2012-07-15 08:38:20 -04:00
|
|
|
trItem->transactionNumber = transN;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
|
|
|
// also make a copy for the resident transaction
|
|
|
|
tr->mTransaction = new RsNxsTransac(*trItem);
|
2012-07-14 13:59:54 -04:00
|
|
|
tr->mTransaction->PeerId(mOwnId);
|
2012-07-15 08:38:20 -04:00
|
|
|
tr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
|
|
|
// signal peer to prepare for transaction
|
|
|
|
sendItem(trItem);
|
|
|
|
|
|
|
|
locked_addTransaction(tr);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
const std::string& peer = item->PeerId();
|
|
|
|
|
|
|
|
GxsMsgMetaResult metaResult;
|
|
|
|
GxsMsgReq req;
|
|
|
|
req[item->grpId] = std::vector<std::string>();
|
|
|
|
mDataStore->retrieveGxsMsgMetaData(req, metaResult);
|
|
|
|
|
|
|
|
std::vector<RsGxsMsgMetaData*>& msgMeta = metaResult[item->grpId];
|
|
|
|
|
|
|
|
if(req.empty()){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<RsGxsMsgMetaData*>::iterator vit = msgMeta.begin();
|
|
|
|
|
|
|
|
NxsTransaction* tr = new NxsTransaction();
|
|
|
|
std::list<RsNxsItem*>& itemL = tr->mItems;
|
|
|
|
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
|
|
|
for(; vit != msgMeta.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsMsgMetaData* m = *vit;
|
|
|
|
RsNxsSyncMsgItem* mItem = new
|
|
|
|
RsNxsSyncMsgItem(mServType);
|
|
|
|
mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
mItem->grpId = m->mGroupId;
|
|
|
|
mItem->msgId = m->mMsgId;
|
|
|
|
mItem->PeerId(peer);
|
|
|
|
mItem->transactionNumber = transN;
|
|
|
|
itemL.push_back(mItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
RsNxsTransac* trItem = new RsNxsTransac(mServType);
|
|
|
|
trItem->transactFlag = RsNxsTransac::FLAG_BEGIN_P1
|
|
|
|
| RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP;
|
|
|
|
|
|
|
|
trItem->nItems = itemL.size();
|
|
|
|
|
|
|
|
trItem->timestamp = 0;
|
|
|
|
trItem->PeerId(peer);
|
|
|
|
trItem->transactionNumber = transN;
|
|
|
|
|
|
|
|
// also make a copy for the resident transaction
|
|
|
|
tr->mTransaction = new RsNxsTransac(*trItem);
|
|
|
|
tr->mTransaction->PeerId(mOwnId);
|
|
|
|
tr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
|
|
|
|
|
|
|
// signal peer to prepare for transaction
|
|
|
|
sendItem(trItem);
|
|
|
|
|
|
|
|
locked_addTransaction(tr);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
/** inherited methods **/
|
|
|
|
|
|
|
|
void RsGxsNetService::pauseSynchronisation(bool enabled)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::setSyncAge(uint32_t age)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/** NxsTransaction definition **/
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_STARTING = 0x0001; // when
|
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_RECEIVING = 0x0002; // begin receiving items for incoming trans
|
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_SENDING = 0x0004; // begin sending items for outgoing trans
|
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_COMPLETED = 0x008;
|
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_FAILED = 0x0010;
|
|
|
|
const uint8_t NxsTransaction::FLAG_STATE_WAITING_CONFIRM = 0x0020;
|
|
|
|
|
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
NxsTransaction::NxsTransaction()
|
2012-07-14 13:59:54 -04:00
|
|
|
: mFlag(0), mTimeOut(0), mTransaction(NULL) {
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
NxsTransaction::~NxsTransaction(){
|
|
|
|
|
2012-06-16 09:59:40 -04:00
|
|
|
std::list<RsNxsItem*>::iterator lit = mItems.begin();
|
|
|
|
|
|
|
|
for(; lit != mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
delete *lit;
|
|
|
|
*lit = NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
delete mTransaction;
|
2012-06-16 09:59:40 -04:00
|
|
|
mTransaction = NULL;
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|