|
Mixe for Privacy and Anonymity in the Internet
|
Data structure that stores all information about the currently open Mix channels. More...
#include <CAFirstMixChannelList.hpp>
Public Member Functions | |
| CAFirstMixChannelList () | |
| ~CAFirstMixChannelList () | |
| fmHashTableEntry * | add (CAMuxSocket *pMuxSocket, const UINT8 peerIP[4], CAQueue *pQueueSend, UINT8 *controlChannelKeyRecv, UINT8 *controlChannelKeySent) |
| Adds a new TCP/IP connection (a new user) to the channel list. | |
| SINT32 | addChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn, CASymCipher *pCipher, HCHANNEL *channelOut) |
| Adds a new channel for a given connection to the channel list. | |
| fmChannelListEntry * | get (CAMuxSocket *pMuxSocket, HCHANNEL channelIn) |
| Returns the information for a given Input-Channel-ID. | |
| fmHashTableEntry * | popTimeoutEntry () |
| fmHashTableEntry * | popTimeoutEntry (bool a_bForce) |
| bool | isTimedOut (fmHashTableEntry *pHashTableEntry) |
| bool | isKickoutForced (fmHashTableEntry *pHashTableEntry) |
| void | setKickoutForced (fmHashTableEntry *pHashTableEntry, bool kickoutForced) |
| bool | forceKickout (fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc) |
| forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control channel belonging to the entry. | |
| SINT32 | pushTimeoutEntry (fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED) |
| adds the entry to the timeout queue with mutex | |
| SINT32 | remove (CAMuxSocket *pMuxSocket) |
| Removes all channels, which belongs to the given connection and the connection itself from the list. | |
| SINT32 | removeChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn) |
| Removes a single channel from the list. | |
| fmHashTableEntry * | getFirst () |
| Gets the first connection of all connections in the list. | |
| fmHashTableEntry * | getNext () |
| Gets the next entry in the connections-list. | |
| fmHashTableEntry * | get (CAMuxSocket *pMuxSocket) |
| Returns the general data stored for a given Socket (user) | |
| fmChannelListEntry * | getFirstChannelForSocket (CAMuxSocket *pMuxSocket) |
| Gets the first channel for a given connection. | |
| fmChannelListEntry * | getNextChannel (fmChannelListEntry *pEntry) |
| Gets the next channel for a given connection. | |
| fmChannelListEntry * | get (HCHANNEL channelOut) |
| Gets the in-channel and all associated information for the given out-channel. | |
| void | setDelayParameters (UINT32 unlimitTraffic, UINT32 bucketGrow, UINT32 intervall) |
| void | decDelayBuckets (UINT32 delayBucketID) |
| bool | hasDelayBuckets (UINT32 delayBucketID) |
Static Public Member Functions | |
| static SINT32 | test () |
Private Member Functions | |
| SINT32 | removeFromTimeoutList (fmHashTableEntry *pHashTableEntry) |
| SINT32 | pushTimeoutEntry_internal (fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED) |
| adds the entry to the timeout queue | |
| bool | isKickoutForced_internal (fmHashTableEntry *pHashTableEntry) |
| void | setKickoutForced_internal (fmHashTableEntry *pHashTableEntry, bool kickoutForced) |
| fmHashTableEntry * | popTimeoutEntry_internal (bool a_bForce) |
| UINT32 | countTimeoutEntries () |
| fmChannelListEntry * | get_intern_without_lock (HCHANNEL channelOut) |
| Gets the in-channel and all associated information for the given out-channel. | |
| bool | isTimedOut_internal (fmHashTableEntry *pHashTableEntry) |
Private Attributes | |
| LP_fmHashTableEntry * | m_HashTable |
| The Hash-Table of all connections. | |
| LP_fmChannelListEntry * | m_HashTableOutChannels |
| The Hash-Table of all out-channels. | |
| fmHashTableEntry * | m_listHashTableHead |
| Pointer to the head of a list of all connections. | |
| fmHashTableEntry * | m_listHashTableNext |
| Next Element in the enumeration of all connections. | |
| fmHashTableEntry * | m_listTimoutHead |
| Pointer to the head of the timout list of all connections. | |
| fmHashTableEntry * | m_listTimoutFoot |
| CAMutex | m_Mutex |
| This mutex is used in all functions and makes them thread safe. | |
| volatile UINT32 ** | m_pDelayBuckets |
| CAThread * | m_pThreadDelayBucketsLoop |
| CAMutex * | m_pMutexDelayChannel |
| bool | m_bDelayBucketsLoopRun |
| volatile UINT32 | m_u32DelayChannelUnlimitTraffic |
| volatile UINT32 | m_u32DelayChannelBucketGrow |
| volatile UINT32 | m_u32DelayChannelBucketGrowIntervall |
Static Private Attributes | |
| static const SINT32 | EXPIRATION_TIME_SECS = 300 |
Friends | |
| THREAD_RETURN | fml_loopDelayBuckets (void *) |
Data structure that stores all information about the currently open Mix channels.
See [FirstMixChannelList] for more information.
Definition at line 221 of file CAFirstMixChannelList.hpp.
Definition at line 43 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::cleanupNotifier, DELAY_USERS_BUCKET_GROW, DELAY_USERS_BUCKET_GROW_INTERVALL, fml_loopDelayBuckets, m_bDelayBucketsLoopRun, m_HashTable, m_HashTableOutChannels, m_listHashTableHead, m_listHashTableNext, m_listTimoutFoot, m_listTimoutHead, m_pDelayBuckets, m_pMutexDelayChannel, m_pThreadDelayBucketsLoop, m_u32DelayChannelBucketGrow, m_u32DelayChannelBucketGrowIntervall, m_u32DelayChannelUnlimitTraffic, MAX_HASH_KEY, MAX_POLLFD, CAThread::setMainLoop(), and CAThread::start().
Referenced by test().
{
m_HashTable=new LP_fmHashTableEntry[MAX_HASH_KEY];
memset(m_HashTable,0,sizeof(LP_fmHashTableEntry)*MAX_HASH_KEY);
for(int i=0;i<MAX_HASH_KEY;i++)
{
m_HashTable[i]=new fmHashTableEntry;
memset(m_HashTable[i],0,sizeof(fmHashTableEntry));
#ifdef PAYMENT
m_HashTable[i]->cleanupNotifier = new CAConditionVariable();
#endif
}
m_listHashTableHead=NULL;
m_listHashTableNext=NULL;
#ifdef PAYMENT
m_listTimoutHead = NULL;
m_listTimoutFoot = NULL;
#endif
m_HashTableOutChannels=new LP_fmChannelListEntry[0x10000];
memset(m_HashTableOutChannels,0,sizeof(LP_fmChannelListEntry)*0x10000);
#ifdef DO_TRACE
m_aktAlloc=m_maxAlloc=0;
#endif
#ifdef DELAY_USERS
m_u32DelayChannelUnlimitTraffic=DELAY_USERS_TRAFFIC;
m_u32DelayChannelBucketGrow=DELAY_USERS_BUCKET_GROW;
m_u32DelayChannelBucketGrowIntervall=DELAY_USERS_BUCKET_GROW_INTERVALL;
m_pDelayBuckets=new volatile UINT32*[MAX_POLLFD];
memset(m_pDelayBuckets,0,sizeof(UINT32*)*MAX_POLLFD);
m_pMutexDelayChannel=new CAMutex();
m_pThreadDelayBucketsLoop=new CAThread((UINT8*)"Delay Channel Thread");
m_bDelayBucketsLoopRun=true;
m_pThreadDelayBucketsLoop->setMainLoop(fml_loopDelayBuckets);
m_pThreadDelayBucketsLoop->start(this);
#endif
}
Definition at line 80 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::cleanupNotifier, CAThread::join(), m_bDelayBucketsLoopRun, m_HashTable, m_HashTableOutChannels, m_pDelayBuckets, m_pMutexDelayChannel, m_pThreadDelayBucketsLoop, and MAX_HASH_KEY.
{
#ifdef DELAY_USERS
m_bDelayBucketsLoopRun=false;
m_pThreadDelayBucketsLoop->join();
delete m_pThreadDelayBucketsLoop;
m_pThreadDelayBucketsLoop = NULL;
delete m_pMutexDelayChannel;
m_pMutexDelayChannel = NULL;
delete []m_pDelayBuckets;
m_pDelayBuckets = NULL;
#endif
for(int i=0;i<MAX_HASH_KEY;i++)
{
#ifdef PAYMENT
delete m_HashTable[i]->cleanupNotifier;
m_HashTable[i]->cleanupNotifier = NULL;
#endif
delete m_HashTable[i];
m_HashTable[i] = NULL;
}
delete []m_HashTable;
m_HashTable = NULL;
delete []m_HashTableOutChannels;
m_HashTableOutChannels = NULL;
}
| fmHashTableEntry * CAFirstMixChannelList::add | ( | CAMuxSocket * | pMuxSocket, |
| const UINT8 | peerIP[4], | ||
| CAQueue * | pQueueSend, | ||
| UINT8 * | controlChannelKeySent, | ||
| UINT8 * | controlChannelKeyRecv | ||
| ) |
Adds a new TCP/IP connection (a new user) to the channel list.
| pMuxSocket | the new connection (from a user) |
| peerIP | the IP of the user, so that we can remove it later from the CAIPList |
| pQueueSend | the send-queue to use for this connection |
| the | fmHashTableEntry of the newly added connection |
| NULL | if an error occured |
Definition at line 116 of file CAFirstMixChannelList.cpp.
References BEGIN_STACK, t_fmhashtableentry::bRecoverTimeout, t_fmhashtableentry::cNumberOfChannels, t_fmhashtableentry::delayBucket, t_fmhashtableentry::delayBucketID, FINISH_STACK, CAMuxSocket::getCASocket(), getcurrentTimeMillis(), CAMuxSocket::getHashKey(), CASocket::getPeerPort(), getRandom(), t_fmhashtableentry::id, INIT_STACK, t_fmhashtableentry::kickoutSendRetries, t_fmhashtableentry::list_HashEntries, MAX_HASH_KEY, MAX_KICKOUT_RETRIES, MAX_POLLFD, t_fmhashtableentry::next, t_fmhashtableentry::pAccountingInfo, t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::pControlMessageQueue, t_fmhashtableentry::peerIP, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, t_fmhashtableentry::prev, SAVE_STACK, and t_fmhashtableentry::uAlreadySendPacketSize.
Referenced by CAFirstMix::doUserLogin_internal(), and test().
{
INIT_STACK;
BEGIN_STACK("CAFirstMixChannelList::add");
if(pMuxSocket==NULL)
{
FINISH_STACK("CAFirstMixChannelList::add (null socket)");
return NULL;
}
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
{
FINISH_STACK("CAFirstMixChannelList::add (invalid hash key)");
return NULL;
}
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
if(pHashTableEntry->pMuxSocket!=NULL) //the entry in the hashtable for this socket (hashkey) must be empty
{
FINISH_STACK("CAFirstMixChannelList::add (socket exists)");
m_Mutex.unlock();
return NULL;
}
//SAVE_STACK("CAFirstMixChannelList::add", "initialising table entry");
#ifdef CH_LOG_STUDY
pHashTableEntry->channelOpenedLastIntervalTS = 0;
#endif
pHashTableEntry->pMuxSocket=pMuxSocket;
pHashTableEntry->pQueueSend=pQueueSend;
pHashTableEntry->pControlMessageQueue = new CAQueue();
pHashTableEntry->pControlChannelDispatcher = new CAControlChannelDispatcher(pHashTableEntry->pControlMessageQueue,controlChannelKeyRecv,controlChannelKeySent);
pHashTableEntry->uAlreadySendPacketSize=-1;
pHashTableEntry->cNumberOfChannels=0;
#ifdef LOG_TRAFFIC_PER_USER
pHashTableEntry->trafficIn=0;
pHashTableEntry->trafficOut=0;
getcurrentTimeMillis(pHashTableEntry->timeCreated);
#endif
#ifdef LOG_DIALOG
pHashTableEntry->strDialog=new UINT8[strlen((char*)strDialog)+1];
strcpy((char*)pHashTableEntry->strDialog,(char*)strDialog);
#endif
// TODO Collisions? Is the id still used somewhere?
//Yes it is --> for logging to match login /logout
//collisions in a hard seens are an issue, but are very unlikely; and because it is only for logging it does not really matter...
getRandom(&(pHashTableEntry->id));
#ifdef PAYMENT
pHashTableEntry->pAccountingInfo=NULL;
#endif
SAVE_STACK("CAFirstMixChannelList::add", "copying peer IP");
memcpy(pHashTableEntry->peerIP,peerIP,4);
#ifdef DATA_RETENTION_LOG
pHashTableEntry->peerPort=pMuxSocket->getCASocket()->getPeerPort();
#endif
#ifdef DELAY_USERS
m_pMutexDelayChannel->lock();
pHashTableEntry->delayBucket=m_u32DelayChannelUnlimitTraffic; //can always send some first packets
for(UINT32 i=0;i<MAX_POLLFD;i++)
{
if(m_pDelayBuckets[i]==NULL)
{
pHashTableEntry->delayBucketID=i;
break;
}
}
m_pDelayBuckets[pHashTableEntry->delayBucketID]=&pHashTableEntry->delayBucket;
m_pMutexDelayChannel->unlock();
#endif
SAVE_STACK("CAFirstMixChannelList::add", "inserting in connection list");
//now insert the new connection in the list of all open connections
if(m_listHashTableHead==NULL) //if first one
{
pHashTableEntry->list_HashEntries.next=NULL;
}
else
{//add to the head of the double linked list
pHashTableEntry->list_HashEntries.next=m_listHashTableHead;
m_listHashTableHead->list_HashEntries.prev=pHashTableEntry;
}
pHashTableEntry->list_HashEntries.prev=NULL;
m_listHashTableHead=pHashTableEntry;
SAVE_STACK("CAFirstMixChannelList::add", "inserting in timout list");
// insert in timeout list; entries are added to the foot of the list
#ifdef PAYMENT
pHashTableEntry->bRecoverTimeout = true;
pHashTableEntry->kickoutSendRetries = MAX_KICKOUT_RETRIES;
/* Hot fix: push timeout entry explicitly to avoid
* confusion, when timeout occurs during AI login
*/
//pushTimeoutEntry_internal(pHashTableEntry);
#endif
m_Mutex.unlock();
FINISH_STACK("CAFirstMixChannelList::add");
return pHashTableEntry;
}
| SINT32 CAFirstMixChannelList::addChannel | ( | CAMuxSocket * | pMuxSocket, |
| HCHANNEL | channelIn, | ||
| CASymCipher * | pCipher, | ||
| HCHANNEL * | channelOut | ||
| ) |
Adds a new channel for a given connection to the channel list.
Also a new out-channel id is generated and returned.
| pMuxSocket | the connection from the user |
| channelIn | the channel, which should be added |
| pCipher | the symmetric cipher associated with this channel |
| channelOut | a pointer to the place, there the new generated out-channel id is stored |
| E_SUCCESS | if successful |
| E_UNKNOWN | in case of an error |
Definition at line 235 of file CAFirstMixChannelList.cpp.
References t_firstmixchannellist::bIsSuspended, t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_fmhashtableentry::cNumberOfChannels, E_SUCCESS, E_UNKNOWN, get_intern_without_lock(), CAMuxSocket::getHashKey(), getRandom(), t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_Mutex, MAX_HASH_KEY, MAX_NUMBER_OF_CHANNELS, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_firstmixchannellist::pCipher, t_firstmixchannellist::pHead, t_fmhashtableentry::pMuxSocket, t_firstmixchannellist::prev, CAMsg::printMsg(), and CAMutex::unlock().
Referenced by CAFirstMixB::loop(), CAFirstMixA::loop(), and test().
{
if(pMuxSocket==NULL||channelOut==NULL)
return E_UNKNOWN;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return E_UNKNOWN;
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
if(pHashTableEntry->pMuxSocket==NULL||pHashTableEntry->cNumberOfChannels>=MAX_NUMBER_OF_CHANNELS)
{
CAMsg::printMsg(LOG_DEBUG,"More than 50 channels!\n");
m_Mutex.unlock();
return E_UNKNOWN;
}
fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
#ifndef DO_TRACE
fmChannelListEntry* pNewEntry=new fmChannelListEntry;
#else
fmChannelListEntry* pNewEntry=newChannelListEntry();
#endif
memset(pNewEntry,0,sizeof(fmChannelListEntry));
pNewEntry->pCipher=pCipher;
pNewEntry->channelIn=channelIn;
do
{
getRandom(channelOut); //get new Random OUT-CHANNEL-ID
} while(*channelOut<256||get_intern_without_lock(*channelOut)!=NULL); //until it is unused...
pNewEntry->channelOut=*channelOut;
pNewEntry->bIsSuspended=false;
pNewEntry->pHead=pHashTableEntry;
#ifdef LOG_CHANNEL
pNewEntry->packetsInFromUser=0;
pNewEntry->packetsOutToUser=0;
#endif
#ifdef SSL_HACK
pNewEntry->downStreamBytes = 0;
#endif
//add to the channel list for the given connection
if(pEntry==NULL) //First Entry to the channel list
{
pNewEntry->list_InChannelPerSocket.next=NULL;
pNewEntry->list_InChannelPerSocket.prev=NULL;
}
else
{
pNewEntry->list_InChannelPerSocket.next=pEntry;
pNewEntry->list_InChannelPerSocket.prev=NULL;
pEntry->list_InChannelPerSocket.prev=pNewEntry;
}
pHashTableEntry->pChannelList=pNewEntry;
//add to the out-channel list
hashkey=(*channelOut)&0x0000FFFF;
pEntry=m_HashTableOutChannels[hashkey];
if(pEntry!=NULL) //Hash Table Bucket Over run....
{
pNewEntry->list_OutChannelHashTable.prev=NULL;
pNewEntry->list_OutChannelHashTable.next=pEntry;
pEntry->list_OutChannelHashTable.prev=pNewEntry;
}
m_HashTableOutChannels[hashkey]=pNewEntry;
pHashTableEntry->cNumberOfChannels++;
m_Mutex.unlock();
return E_SUCCESS;
}
| UINT32 CAFirstMixChannelList::countTimeoutEntries | ( | ) | [private] |
Definition at line 492 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutHead, and t_fmhashtableentry::next.
{
fmHashTableEntry* pHashTableEntry;
UINT32 count = 0;
for (pHashTableEntry = m_listTimoutHead; pHashTableEntry != NULL;
count++, pHashTableEntry = pHashTableEntry->list_TimeoutHashEntries.next);
return count;
}
| void CAFirstMixChannelList::decDelayBuckets | ( | UINT32 | delayBucketID | ) |
Definition at line 1200 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, MAX_POLLFD, and CAMutex::unlock().
Referenced by CAFirstMixA::sendToUsers().
{
m_pMutexDelayChannel->lock();
if(delayBucketID < MAX_POLLFD)
{
if(m_pDelayBuckets[delayBucketID] != NULL)
{
*(m_pDelayBuckets[delayBucketID]) -= ( (*(m_pDelayBuckets[delayBucketID])) > 0 ) ? 1 : 0;
}
/*CAMsg::printMsg(LOG_DEBUG,"DelayBuckets decrementing ID %u downto %u\n",
delayBucketID, (*(m_pDelayBuckets[delayBucketID])) );*/
}
m_pMutexDelayChannel->unlock();
}
| bool CAFirstMixChannelList::forceKickout | ( | fmHashTableEntry * | pHashTableEntry, |
| const XERCES_CPP_NAMESPACE::DOMDocument * | pErrDoc | ||
| ) |
forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control channel belonging to the entry.
returns true if pHashTableEntry is still valid, false otherwise
Definition at line 405 of file CAFirstMixChannelList.cpp.
References KICKOUT_FORCED, CAMutex::lock(), m_Mutex, t_fmhashtableentry::pAccountingInfo, t_accountinginfo::pControlChannel, t_fmhashtableentry::pMuxSocket, CAAbstractControlChannel::sendXMLMessage(), setKickoutForced_internal(), and CAMutex::unlock().
Referenced by CAFirstMix::forceKickout().
{
bool ret = false;
m_Mutex.lock();
ret = (pHashTableEntry->pMuxSocket != NULL);
if(ret)
{
if(pErrDoc != NULL)
{
//NOTE: accessing the control channel in this case works without further locking,
//because the control channel is only deleted when the Dispatcher deletes all channels.
//This happens when the table entry is removed by CAFirstMixChannelList::remove
//which locks over m_Mutex.
pHashTableEntry->pAccountingInfo->pControlChannel->sendXMLMessage(pErrDoc);
}
setKickoutForced_internal(pHashTableEntry, KICKOUT_FORCED);
}
m_Mutex.unlock();
return ret;
}
| fmChannelListEntry * CAFirstMixChannelList::get | ( | CAMuxSocket * | pMuxSocket, |
| HCHANNEL | channelIn | ||
| ) |
Returns the information for a given Input-Channel-ID.
| pMuxSocket | the connection from the user |
| channelIn | the channel id |
| NULL | if not found |
Definition at line 333 of file CAFirstMixChannelList.cpp.
References t_firstmixchannellist::channelIn, CAMuxSocket::getHashKey(), t_firstmixchannellist::list_InChannelPerSocket, CAMutex::lock(), m_HashTable, m_Mutex, MAX_HASH_KEY, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, and CAMutex::unlock().
Referenced by CAFirstMix::doUserLogin_internal(), CAFirstMixA::finishPacket(), CAFirstMixB::loop(), and CAFirstMixA::loop().
{
if(pMuxSocket==NULL)
return NULL;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return NULL;
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
while(pEntry!=NULL)
{
if(pEntry->channelIn==channelIn)
{
m_Mutex.unlock();
return pEntry;
}
pEntry=pEntry->list_InChannelPerSocket.next;
}
m_Mutex.unlock();
return NULL;
}
| fmHashTableEntry * CAFirstMixChannelList::get | ( | CAMuxSocket * | pMuxSocket | ) |
Returns the general data stored for a given Socket (user)
| pMuxSocket | the connection from the user |
| NULL | if not found |
Definition at line 314 of file CAFirstMixChannelList.cpp.
References CAMuxSocket::getHashKey(), CAMutex::lock(), m_HashTable, m_Mutex, MAX_HASH_KEY, and CAMutex::unlock().
{
if(pMuxSocket==NULL)
return NULL;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return NULL;
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
m_Mutex.unlock();
return pHashTableEntry;
}
| fmChannelListEntry* CAFirstMixChannelList::get | ( | HCHANNEL | channelOut | ) | [inline] |
Gets the in-channel and all associated information for the given out-channel.
| channelOut | the out-channel id for which the information is requested |
| NULL | if not found in list |
Definition at line 329 of file CAFirstMixChannelList.hpp.
References get_intern_without_lock(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().
{
m_Mutex.lock();
fmChannelListEntry* pEntry=get_intern_without_lock(channelOut);
m_Mutex.unlock();
return pEntry;
}
| fmChannelListEntry* CAFirstMixChannelList::get_intern_without_lock | ( | HCHANNEL | channelOut | ) | [inline, private] |
Gets the in-channel and all associated information for the given out-channel.
This method is NOT thread safe (and so only for internal use)
| channelOut | the out-channel id for which the information is requested |
| NULL | if not found in list |
Definition at line 306 of file CAFirstMixChannelList.hpp.
References t_firstmixchannellist::channelOut, t_firstmixchannellist::list_OutChannelHashTable, m_HashTableOutChannels, and t_firstmixchannellist::next.
Referenced by addChannel(), and get().
{
fmChannelListEntry* pEntry=m_HashTableOutChannels[channelOut&0x0000FFFF];
while(pEntry!=NULL)
{
if(pEntry->channelOut==channelOut)
{
return pEntry;
}
pEntry=pEntry->list_OutChannelHashTable.next;
}
return NULL;
}
Gets the first connection of all connections in the list.
| NULL | if no connection is in the list |
Definition at line 1081 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::list_HashEntries, CAMutex::lock(), m_listHashTableHead, m_listHashTableNext, m_Mutex, t_fmhashtableentry::next, and CAMutex::unlock().
Referenced by CAFirstMix::clean(), CAFirstMixB::loop(), CAFirstMixA::loop(), and CAFirstMixA::sendToUsers().
{
m_Mutex.lock();
if(m_listHashTableHead!=NULL)
m_listHashTableNext=m_listHashTableHead->list_HashEntries.next;
else
m_listHashTableNext=NULL;
m_Mutex.unlock();
return m_listHashTableHead;
}
| fmChannelListEntry * CAFirstMixChannelList::getFirstChannelForSocket | ( | CAMuxSocket * | pMuxSocket | ) |
Gets the first channel for a given connection.
| pMuxSocket | the connection from the user |
| NULL | if no channel for this connection exists at the moment |
Definition at line 1113 of file CAFirstMixChannelList.cpp.
References CAMuxSocket::getHashKey(), m_HashTable, MAX_HASH_KEY, and t_fmhashtableentry::pChannelList.
Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMixB::loop(), and CAFirstMixA::notifyAllUserChannels().
{
if(pMuxSocket==NULL)
return NULL;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return NULL;
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
return pHashTableEntry->pChannelList;
}
Gets the next entry in the connections-list.
| NULL | in case of an error |
Definition at line 1097 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::list_HashEntries, CAMutex::lock(), m_listHashTableNext, m_Mutex, t_fmhashtableentry::next, and CAMutex::unlock().
Referenced by CAFirstMix::clean(), CAFirstMixB::loop(), CAFirstMixA::loop(), and CAFirstMixA::sendToUsers().
{
m_Mutex.lock();
fmHashTableEntry* tmpEntry=m_listHashTableNext;
if(m_listHashTableNext!=NULL)
m_listHashTableNext=m_listHashTableNext->list_HashEntries.next;
m_Mutex.unlock();
return tmpEntry;
}
Gets the next channel for a given connection.
| pEntry | a entry returned by a previos call to getFirstChannelForSocket() or getNextChannel() |
| NULL | if there are no more channels for this connection |
Definition at line 1130 of file CAFirstMixChannelList.cpp.
References t_firstmixchannellist::list_InChannelPerSocket, and t_firstmixchannellist::next.
Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMixB::loop(), and CAFirstMixA::notifyAllUserChannels().
{
if(pEntry==NULL)
return NULL;
return pEntry->list_InChannelPerSocket.next;
}
| bool CAFirstMixChannelList::hasDelayBuckets | ( | UINT32 | delayBucketID | ) |
Definition at line 1215 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, MAX_POLLFD, and CAMutex::unlock().
Referenced by CAFirstMixA::sendToUsers().
{
bool ret = false;
m_pMutexDelayChannel->lock();
if(delayBucketID < MAX_POLLFD)
{
if(m_pDelayBuckets[delayBucketID] != NULL)
{
ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 );
}
}
m_pMutexDelayChannel->unlock();
return ret;
}
| bool CAFirstMixChannelList::isKickoutForced | ( | fmHashTableEntry * | pHashTableEntry | ) |
Definition at line 384 of file CAFirstMixChannelList.cpp.
References isKickoutForced_internal(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().
Referenced by CAFirstMixA::checkUserConnections().
{
bool ret = false;
m_Mutex.lock();
ret = isKickoutForced_internal(pHashTableEntry);
m_Mutex.unlock();
return ret;
}
| bool CAFirstMixChannelList::isKickoutForced_internal | ( | fmHashTableEntry * | pHashTableEntry | ) | [inline, private] |
Definition at line 433 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::bRecoverTimeout.
Referenced by isKickoutForced().
{
return !(pHashTableEntry->bRecoverTimeout);
}
| bool CAFirstMixChannelList::isTimedOut | ( | fmHashTableEntry * | pHashTableEntry | ) |
Definition at line 373 of file CAFirstMixChannelList.cpp.
References isTimedOut_internal(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().
Referenced by CAFirstMixA::checkUserConnections().
{
bool ret = false;
m_Mutex.lock();
ret = isTimedOut_internal(pHashTableEntry);
m_Mutex.unlock();
return ret;
}
| bool CAFirstMixChannelList::isTimedOut_internal | ( | fmHashTableEntry * | pHashTableEntry | ) | [inline, private] |
Definition at line 428 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::list_TimeoutHashEntries, and t_fmhashtableentry::timoutSecs.
Referenced by isTimedOut(), and popTimeoutEntry_internal().
{
return (pHashTableEntry->list_TimeoutHashEntries.timoutSecs <= time(NULL));
}
| fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry | ( | ) | [inline] |
Definition at line 357 of file CAFirstMixChannelList.cpp.
Referenced by CAFirstMixA::checkUserConnections(), and CAFirstMixA::shutDown().
{
return popTimeoutEntry(false);
}
| fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry | ( | bool | a_bForce | ) |
| if | set to true, forces to return the next timeout enty or NULL if none are left in the queue |
Definition at line 362 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_Mutex, popTimeoutEntry_internal(), and CAMutex::unlock().
{
fmHashTableEntry* ret;
m_Mutex.lock();
ret = popTimeoutEntry_internal(a_bForce);
m_Mutex.unlock();
return ret;
}
| fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry_internal | ( | bool | a_bForce | ) | [private] |
Definition at line 451 of file CAFirstMixChannelList.cpp.
References E_SUCCESS, isTimedOut_internal(), m_listTimoutHead, CAMsg::printMsg(), and removeFromTimeoutList().
Referenced by popTimeoutEntry().
{
fmHashTableEntry* pHashTableEntry;
if (m_listTimoutHead == NULL)
{
// there are not entries in the list
return NULL;
}
pHashTableEntry = m_listTimoutHead;
if (a_bForce || isTimedOut_internal(pHashTableEntry))
{
if (removeFromTimeoutList(pHashTableEntry) == E_SUCCESS)
{
return pHashTableEntry;
}
else
{
CAMsg::printMsg(LOG_CRIT,
"CAFirstMixChannelList:popTimeoutEntry_internal: Could not remove expired entry from timeout list!\n");
}
}
return NULL;
}
| SINT32 CAFirstMixChannelList::pushTimeoutEntry | ( | fmHashTableEntry * | pHashTableEntry, |
| bool | kickoutForced = !KICKOUT_FORCED |
||
| ) |
adds the entry to the timeout queue with mutex
Definition at line 480 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_Mutex, pushTimeoutEntry_internal(), and CAMutex::unlock().
Referenced by CAFirstMixA::accountTrafficDownstream(), CAFirstMixA::accountTrafficUpstream(), CAFirstMixA::checkUserConnections(), CAFirstMix::doUserLogin_internal(), and CAFirstMixA::loop().
{
SINT32 ret;
m_Mutex.lock();
ret = pushTimeoutEntry_internal(pHashTableEntry, kickoutForced);
m_Mutex.unlock();
return ret;
}
| SINT32 CAFirstMixChannelList::pushTimeoutEntry_internal | ( | fmHashTableEntry * | pHashTableEntry, |
| bool | kickoutForced = !KICKOUT_FORCED |
||
| ) | [private] |
adds the entry to the timeout queue
renews the timestamp for the timeout list does not affect forced kickouts.
Definition at line 509 of file CAFirstMixChannelList.cpp.
References BEGIN_STACK, E_SUCCESS, E_UNKNOWN, EXPIRATION_TIME_SECS, FINISH_STACK, INIT_STACK, t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutFoot, m_listTimoutHead, t_fmhashtableentry::next, t_fmhashtableentry::prev, removeFromTimeoutList(), setKickoutForced_internal(), and t_fmhashtableentry::timoutSecs.
Referenced by pushTimeoutEntry().
{
if (pHashTableEntry == NULL)
{
return E_UNKNOWN;
}
/*if(isKickoutForced_internal(pHashTableEntry))
{
return E_SUCCESS;
}*/
INIT_STACK;
BEGIN_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");
//CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list before push: %d\n", countTimeoutEntries());
pHashTableEntry->list_TimeoutHashEntries.timoutSecs = time(NULL) + EXPIRATION_TIME_SECS;
//SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "removing from timeout list");
// remove from timeout list if needed before adding it to the end
removeFromTimeoutList(pHashTableEntry);
setKickoutForced_internal(pHashTableEntry, kickoutForced);
if (m_listTimoutFoot == NULL)
{
//SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new first entry");
// this is the first entry in the list
pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
m_listTimoutHead = pHashTableEntry;
}
else
{
//SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new last entry");
// this is the new last entry in the list
m_listTimoutFoot->list_TimeoutHashEntries.next = pHashTableEntry;
pHashTableEntry->list_TimeoutHashEntries.prev = m_listTimoutFoot;
}
pHashTableEntry->list_TimeoutHashEntries.next = NULL;
m_listTimoutFoot = pHashTableEntry;
//CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list after push: %d\n", countTimeoutEntries());
FINISH_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");
//CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: pushed entry %x!\n", pHashTableEntry);
return E_SUCCESS;
}
| SINT32 CAFirstMixChannelList::remove | ( | CAMuxSocket * | pMuxSocket | ) |
Removes all channels, which belongs to the given connection and the connection itself from the list.
| pMuxSocket | the connection from the user |
| E_SUCCESS | if successful |
| E_UNKNOWN | in case of an error |
Definition at line 640 of file CAFirstMixChannelList.cpp.
References t_firstmixchannellist::channelOut, t_fmhashtableentry::cleanupNotifier, t_fmhashtableentry::delayBucketID, CAControlChannelDispatcher::deleteAllControlChannels(), E_SUCCESS, E_UNKNOWN, CAMuxSocket::getHashKey(), t_fmhashtableentry::list_HashEntries, t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_listHashTableHead, m_listHashTableNext, m_Mutex, m_pDelayBuckets, m_pMutexDelayChannel, MAX_HASH_KEY, t_fmhashtableentry::next, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::pControlMessageQueue, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::prev, t_firstmixchannellist::prev, removeFromTimeoutList(), CAConditionVariable::signal(), and CAMutex::unlock().
Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMix::doUserLogin_internal(), CAFirstMixB::loop(), and test().
{
if(pMuxSocket==NULL)
return E_UNKNOWN;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return E_UNKNOWN;
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
if(pHashTableEntry->pMuxSocket==NULL) //this connection is not in the list
{
m_Mutex.unlock();
return E_UNKNOWN;
}
#ifdef DELAY_USERS
m_pMutexDelayChannel->lock();
m_pDelayBuckets[pHashTableEntry->delayBucketID]=NULL;
m_pMutexDelayChannel->unlock();
#endif
pHashTableEntry->pControlChannelDispatcher->deleteAllControlChannels();
delete pHashTableEntry->pControlChannelDispatcher; //deletes the dispatcher and all associated control channels
delete pHashTableEntry->pControlMessageQueue;
pHashTableEntry->pControlChannelDispatcher = NULL;
pHashTableEntry->pControlMessageQueue = NULL;
if(m_listHashTableNext==pHashTableEntry) //adjust the enumeration over all connections (@see getNext())
m_listHashTableNext=pHashTableEntry->list_HashEntries.next;
if(pHashTableEntry->list_HashEntries.prev==NULL) //if entry is the head of the connection list
{
if(pHashTableEntry->list_HashEntries.next==NULL) //if entry is also the last (so the only one in the list..)
{
m_listHashTableHead=NULL; //list is now empty
}
else
{//remove the head of the list
m_listHashTableHead=pHashTableEntry->list_HashEntries.next;
m_listHashTableHead->list_HashEntries.prev=NULL;
}
}
else
{ //the connection is not the head of the list
if(pHashTableEntry->list_HashEntries.next==NULL)
{//the connection is the last element in the list
pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=NULL;
}
else
{//its a simple middle element
pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=pHashTableEntry->list_HashEntries.next;
pHashTableEntry->list_HashEntries.next->list_HashEntries.prev=pHashTableEntry->list_HashEntries.prev;
}
}
#ifdef PAYMENT
removeFromTimeoutList(pHashTableEntry);
#endif
fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
fmChannelListEntry* pTmpEntry;
while(pEntry!=NULL)//for all channels....
{
//remove the out channel form the out channel hast table
hashkey=pEntry->channelOut&0x0000FFFF;
pTmpEntry=m_HashTableOutChannels[hashkey];
while(pTmpEntry!=NULL)
{
if(pTmpEntry->channelOut==pEntry->channelOut)
{//we have found the entry
if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //it's the head
{
if(pTmpEntry->list_OutChannelHashTable.next==NULL)
{//it's also the last Element
m_HashTableOutChannels[hashkey]=NULL; //empty this hash bucket
}
else
{
pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=NULL;
m_HashTableOutChannels[hashkey]=pTmpEntry->list_OutChannelHashTable.next;
}
}
else
{//not the head
if(pTmpEntry->list_OutChannelHashTable.next==NULL)
{//but the last
pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=NULL;
}
else
{//a middle element
pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=pTmpEntry->list_OutChannelHashTable.next;
pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=pTmpEntry->list_OutChannelHashTable.prev;
}
}
break;
}
pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
}
pTmpEntry=pEntry->list_InChannelPerSocket.next;
#ifndef DO_TRACE
delete pEntry;
pEntry = NULL;
#else
deleteChannelListEntry(pEntry);
#endif
pEntry=pTmpEntry;
}
/* already done by pHashTableEntry->pControlChannelDispatcher->deleteAllControlChannels();
#ifdef PAYMENT
// cleanup accounting information
CAAccountingInstance::cleanupTableEntry(pHashTableEntry);
#endif
*/
#ifdef LOG_DIALOG
delete[] pHashTableEntry->strDialog;
pHashTableEntry->strDialog = NULL;
#endif
#ifdef PAYMENT
CAConditionVariable *rescue = pHashTableEntry->cleanupNotifier;
#endif
//TODO: a bit more precise reference cleanup
memset(pHashTableEntry,0,sizeof(fmHashTableEntry)); //'delete' the connection from the connection hash table
#ifdef PAYMENT
pHashTableEntry->cleanupNotifier = rescue;
pHashTableEntry->cleanupNotifier->lock();
pHashTableEntry->cleanupNotifier->signal();
pHashTableEntry->cleanupNotifier->unlock();
#endif
m_Mutex.unlock();
return E_SUCCESS;
}
| SINT32 CAFirstMixChannelList::removeChannel | ( | CAMuxSocket * | pMuxSocket, |
| HCHANNEL | channelIn | ||
| ) |
Removes a single channel from the list.
| pMuxSocket | the connection from the user |
| channelIn | the channel, which should be removed |
| E_SUCCESS | if successful |
| E_UNKNOWN | in case of an error |
Definition at line 980 of file CAFirstMixChannelList.cpp.
References t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_fmhashtableentry::cNumberOfChannels, E_SUCCESS, E_UNKNOWN, CAMuxSocket::getHashKey(), t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_Mutex, MAX_HASH_KEY, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_fmhashtableentry::pMuxSocket, t_firstmixchannellist::prev, and CAMutex::unlock().
Referenced by CAFirstMixA::finishPacket(), CAFirstMixB::loop(), CAFirstMixA::loop(), and test().
{
if(pMuxSocket==NULL)
return E_UNKNOWN;
SINT32 hashkey=pMuxSocket->getHashKey();
if(hashkey>MAX_HASH_KEY-1||hashkey<0)
return E_UNKNOWN;
m_Mutex.lock();
fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
if(pHashTableEntry->pMuxSocket==NULL)
{
m_Mutex.unlock();
return E_UNKNOWN;
}
fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
while(pEntry!=NULL)
{
if(pEntry->channelIn==channelIn) //search for the channel
{
hashkey=pEntry->channelOut&0x0000FFFF; //remove the out channel from the out channel hash table
fmChannelListEntry*pTmpEntry=m_HashTableOutChannels[hashkey];
while(pTmpEntry!=NULL)
{
if(pTmpEntry->channelOut==pEntry->channelOut)
{//found it in the out channel hash table
if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //head
{
if(pTmpEntry->list_OutChannelHashTable.next==NULL)
{
m_HashTableOutChannels[hashkey]=NULL;
}
else
{
pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=NULL;
m_HashTableOutChannels[hashkey]=pTmpEntry->list_OutChannelHashTable.next;
}
}
else
{
if(pTmpEntry->list_OutChannelHashTable.next==NULL)
{//last element
pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=NULL;
}
else
{//middle element
pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=pTmpEntry->list_OutChannelHashTable.next;
pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=pTmpEntry->list_OutChannelHashTable.prev;
}
}
break;
}
pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
}
//remove the channel from the channel hast table
if(pEntry->list_InChannelPerSocket.prev==NULL) //head
{
if(pEntry->list_InChannelPerSocket.next==NULL)
{//the only element
pHashTableEntry->pChannelList=NULL;
}
else
{
pEntry->list_InChannelPerSocket.next->list_InChannelPerSocket.prev=NULL;
pHashTableEntry->pChannelList=pEntry->list_InChannelPerSocket.next;
}
}
else
{
if(pEntry->list_InChannelPerSocket.next==NULL)
{//the last element
pEntry->list_InChannelPerSocket.prev->list_InChannelPerSocket.next=NULL;
}
else
{//a middle element
pEntry->list_InChannelPerSocket.prev->list_InChannelPerSocket.next=pEntry->list_InChannelPerSocket.next;
pEntry->list_InChannelPerSocket.next->list_InChannelPerSocket.prev=pEntry->list_InChannelPerSocket.prev;
}
}
#ifndef DO_TRACE
delete pEntry;
pEntry = NULL;
#else
deleteChannelListEntry(pEntry);
#endif
pHashTableEntry->cNumberOfChannels--;
m_Mutex.unlock();
return E_SUCCESS;
}
pEntry=pEntry->list_InChannelPerSocket.next; //try next channel
}
m_Mutex.unlock();
return E_UNKNOWN;//not found
}
| SINT32 CAFirstMixChannelList::removeFromTimeoutList | ( | fmHashTableEntry * | pHashTableEntry | ) | [private] |
Definition at line 561 of file CAFirstMixChannelList.cpp.
References E_SUCCESS, E_UNKNOWN, t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutFoot, m_listTimoutHead, t_fmhashtableentry::next, t_fmhashtableentry::prev, and CAMsg::printMsg().
Referenced by popTimeoutEntry_internal(), pushTimeoutEntry_internal(), and remove().
{
if (pHashTableEntry == NULL)
{
return E_UNKNOWN;
}
//CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: removing entry %x!\n", pHashTableEntry);
if (m_listTimoutHead == NULL || m_listTimoutFoot == NULL)
{
// there is no entry in the list; therefore this entry does not need to be removed
return E_SUCCESS;
}
if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL &&
pHashTableEntry->list_TimeoutHashEntries.next == NULL &&
m_listTimoutHead != pHashTableEntry)
{
// this entry is not in the list; it does not need to be removed
return E_SUCCESS;
}
if(m_listTimoutHead == pHashTableEntry) //if entry is the head of the connection list
{
if(m_listTimoutFoot == pHashTableEntry) //if entry is also the last (so the only one in the list..)
{
//list is now empty
m_listTimoutHead = NULL;
m_listTimoutFoot = NULL;
}
else
{
//remove the head of the list
m_listTimoutHead = pHashTableEntry->list_TimeoutHashEntries.next;
}
}
else
{ //the connection is not the head of the list
if(pHashTableEntry->list_TimeoutHashEntries.next == NULL)
{
//the connection is the last element in the list
m_listTimoutFoot = pHashTableEntry->list_TimeoutHashEntries.prev;
m_listTimoutFoot->list_TimeoutHashEntries.next = NULL;
}
else
{
//it is a simple middle element
if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL)
{
CAMsg::printMsg(LOG_CRIT, "CAFirstMixChannelList:removeFromTimeoutList: No previous element!!\n");
}
else
{
pHashTableEntry->list_TimeoutHashEntries.prev->list_TimeoutHashEntries.next = pHashTableEntry->list_TimeoutHashEntries.next;
}
if (pHashTableEntry->list_TimeoutHashEntries.next == NULL)
{
CAMsg::printMsg(LOG_CRIT, "CAFirstMixChanelList:removeFromTimeoutList: No next element!!\n");
}
else
{
pHashTableEntry->list_TimeoutHashEntries.next->list_TimeoutHashEntries.prev = pHashTableEntry->list_TimeoutHashEntries.prev;
}
}
}
pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
pHashTableEntry->list_TimeoutHashEntries.next = NULL;
return E_SUCCESS;
}
| void CAFirstMixChannelList::setDelayParameters | ( | UINT32 | unlimitTraffic, |
| UINT32 | bucketGrow, | ||
| UINT32 | intervall | ||
| ) |
Definition at line 1230 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, m_u32DelayChannelBucketGrow, m_u32DelayChannelBucketGrowIntervall, m_u32DelayChannelUnlimitTraffic, MAX_POLLFD, CAMsg::printMsg(), and CAMutex::unlock().
Referenced by CAFirstMixB::loop(), CAFirstMixA::loop(), and CAFirstMix::reconfigure().
{
m_pMutexDelayChannel->lock();
CAMsg::printMsg(LOG_DEBUG,"CAFirstMixChannelList - Set new traffic limit per user- unlimit: %u bucketgrow: %u intervall %u\n",
unlimitTraffic,bucketGrow,intervall);
m_u32DelayChannelUnlimitTraffic=unlimitTraffic;
m_u32DelayChannelBucketGrow=bucketGrow;
m_u32DelayChannelBucketGrowIntervall=intervall;
for(UINT32 i=0;i<MAX_POLLFD;i++)
if(m_pDelayBuckets[i]!=NULL)
*(m_pDelayBuckets[i])=m_u32DelayChannelUnlimitTraffic;
m_pMutexDelayChannel->unlock();
}
| void CAFirstMixChannelList::setKickoutForced | ( | fmHashTableEntry * | pHashTableEntry, |
| bool | kickoutForced | ||
| ) |
Definition at line 392 of file CAFirstMixChannelList.cpp.
References CAMutex::lock(), m_Mutex, setKickoutForced_internal(), and CAMutex::unlock().
Referenced by CAFirstMixA::accountTrafficDownstream(), and CAFirstMixA::accountTrafficUpstream().
{
m_Mutex.lock();
setKickoutForced_internal(pHashTableEntry, kickoutForced);
m_Mutex.unlock();
}
| void CAFirstMixChannelList::setKickoutForced_internal | ( | fmHashTableEntry * | pHashTableEntry, |
| bool | kickoutForced | ||
| ) | [inline, private] |
Definition at line 438 of file CAFirstMixChannelList.cpp.
References t_fmhashtableentry::bRecoverTimeout, and CAMsg::printMsg().
Referenced by forceKickout(), pushTimeoutEntry_internal(), and setKickoutForced().
{
if(!pHashTableEntry->bRecoverTimeout && !kickoutForced )
{
CAMsg::printMsg(LOG_WARNING, "Try to switch back from forced kickout. A forced kickout cannot be undone!\n");
}
else
{
pHashTableEntry->bRecoverTimeout = !kickoutForced;
}
}
| SINT32 CAFirstMixChannelList::test | ( | ) | [static] |
Definition at line 1137 of file CAFirstMixChannelList.cpp.
References add(), addChannel(), CAFirstMixChannelList(), CASocket::create(), E_SUCCESS, CAMuxSocket::getCASocket(), remove(), and removeChannel().
{
CAFirstMixChannelList* pList=new CAFirstMixChannelList();
CAMuxSocket *pMuxSocket=new CAMuxSocket();
pMuxSocket->getCASocket()->create();
UINT8 peerIP[4];
#ifndef LOG_DIALOG
pList->add(pMuxSocket,peerIP,NULL,NULL,NULL);
#else
pList->add(pMuxSocket,peerIP,NULL,(UINT8*)"1");
#endif
#if defined(HAVE_CRTDBG)
_CrtMemState s1, s2, s3;
_CrtMemCheckpoint( &s1 );
#endif
UINT32 /*channelIn,*/i,channelOut;
for(i=0;i<50;i++)
pList->addChannel(pMuxSocket,i,NULL,&channelOut);
for(i=0;i<50;i++)
pList->removeChannel(pMuxSocket,i);
#if defined(HAVE_CRTDBG)
_CrtMemCheckpoint( &s2 );
if ( _CrtMemDifference( &s3, &s1, &s2 ) )
_CrtMemDumpStatistics( &s3 );
#endif
pList->remove(pMuxSocket);
delete pMuxSocket;
pMuxSocket = NULL;
delete pList;
pList = NULL;
return E_SUCCESS;
}
| THREAD_RETURN fml_loopDelayBuckets | ( | void * | ) | [friend] |
Definition at line 1172 of file CAFirstMixChannelList.cpp.
Referenced by CAFirstMixChannelList().
{
INIT_STACK;
BEGIN_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");
CAFirstMixChannelList* pChannelList=(CAFirstMixChannelList*)param;
volatile UINT32** pDelayBuckets=pChannelList->m_pDelayBuckets;
while(pChannelList->m_bDelayBucketsLoopRun)
{
pChannelList->m_pMutexDelayChannel->lock();
UINT32 u32BucketGrow=pChannelList->m_u32DelayChannelBucketGrow;
UINT32 u32MaxBucket=u32BucketGrow*10;
for(UINT32 i=0;i<MAX_POLLFD;i++)
{
if(pDelayBuckets[i]!=NULL&&*(pDelayBuckets[i])<u32MaxBucket)
{
*(pDelayBuckets[i])+=u32BucketGrow;
}
}
pChannelList->m_pMutexDelayChannel->unlock();
msSleep(pChannelList->m_u32DelayChannelBucketGrowIntervall);
}
FINISH_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");
THREAD_RETURN_SUCCESS;
}
const SINT32 CAFirstMixChannelList::EXPIRATION_TIME_SECS = 300 [static, private] |
Definition at line 337 of file CAFirstMixChannelList.hpp.
Referenced by pushTimeoutEntry_internal().
bool CAFirstMixChannelList::m_bDelayBucketsLoopRun [private] |
Definition at line 362 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), fml_loopDelayBuckets(), and ~CAFirstMixChannelList().
The Hash-Table of all connections.
Definition at line 340 of file CAFirstMixChannelList.hpp.
Referenced by addChannel(), CAFirstMixChannelList(), get(), getFirstChannelForSocket(), remove(), removeChannel(), and ~CAFirstMixChannelList().
The Hash-Table of all out-channels.
Definition at line 342 of file CAFirstMixChannelList.hpp.
Referenced by addChannel(), CAFirstMixChannelList(), get_intern_without_lock(), remove(), removeChannel(), and ~CAFirstMixChannelList().
Pointer to the head of a list of all connections.
Definition at line 345 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), getFirst(), and remove().
Next Element in the enumeration of all connections.
Definition at line 347 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), getFirst(), getNext(), and remove().
Definition at line 351 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), pushTimeoutEntry_internal(), and removeFromTimeoutList().
Pointer to the head of the timout list of all connections.
Definition at line 350 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), countTimeoutEntries(), popTimeoutEntry_internal(), pushTimeoutEntry_internal(), and removeFromTimeoutList().
CAMutex CAFirstMixChannelList::m_Mutex [private] |
This mutex is used in all functions and makes them thread safe.
Definition at line 354 of file CAFirstMixChannelList.hpp.
Referenced by addChannel(), forceKickout(), get(), getFirst(), getNext(), isKickoutForced(), isTimedOut(), popTimeoutEntry(), pushTimeoutEntry(), remove(), removeChannel(), and setKickoutForced().
volatile UINT32** CAFirstMixChannelList::m_pDelayBuckets [private] |
Definition at line 359 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), decDelayBuckets(), fml_loopDelayBuckets(), hasDelayBuckets(), remove(), setDelayParameters(), and ~CAFirstMixChannelList().
Definition at line 361 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), decDelayBuckets(), fml_loopDelayBuckets(), hasDelayBuckets(), remove(), setDelayParameters(), and ~CAFirstMixChannelList().
Definition at line 360 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), and ~CAFirstMixChannelList().
volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelBucketGrow [private] |
Definition at line 366 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), fml_loopDelayBuckets(), and setDelayParameters().
volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelBucketGrowIntervall [private] |
Definition at line 367 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), fml_loopDelayBuckets(), and setDelayParameters().
volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelUnlimitTraffic [private] |
Definition at line 365 of file CAFirstMixChannelList.hpp.
Referenced by CAFirstMixChannelList(), and setDelayParameters().
1.7.6.1