Beispiel #1
0
void coalesceIfNecessary(buffer* aBuffer) {

	if (aBuffer->size == 8192) {
		removeBufferFromFreeList(aBuffer, getFreeList(aBuffer->size));
		if (debug) printf("Coalesced to max size\n");
		freeListPointers* freeLists = (freeListPointers*)entryPoint->ptr;

		pageHeaderInfo* pageHeader = (void*)aBuffer->start - sizeof(pageHeaderInfo);
		if (debug) printf("The start is at %p and the page header is at %p\n", aBuffer->start, pageHeader);

		free_page(pageHeader->pageInfo);
		freeLists->numAllocatedPages--;
		if (freeLists->numAllocatedPages == 0) {
			free_page(entryPoint);
			entryPoint = 0;
		}
		
		return;
	}

	buffer* buddy = getBuddy(aBuffer);
	if (debug) printf("Trying to coalesce a buffer of size %i\n", aBuffer->size);
	if (!buddy->isAllocated && buddy->size == aBuffer->size) {
		freeListInfo* freeList = getFreeList(buddy->size);
		removeBufferFromFreeList(buddy, freeList);
		removeBufferFromFreeList(aBuffer, freeList);
		
		buffer* parent = buddy < aBuffer ? buddy : aBuffer;

		parent->size = parent->size*2;
		addBufferToFreeList(parent, getFreeList(parent->size));
		coalesceIfNecessary(parent);
	}
}
/*
 * This is a helper method used to merge a block with it's buddy if both the blocks are
 * free to be merged into one
 */
void merge_memBlock(metadata_t* memBlock)
{
	int freelist_index = log_Base_2(memBlock->size) - 4;
	//We are subtracting 4 because the smallest memory block size we have is 16
	//which should correspond to index 0, so log 16 = 4 - 4 would give us 0

	metadata_t* buddy = getBuddy(memBlock);

	//first defining the cases where we cannot merge
	if(memBlock->size >= SBRK_SIZE)
	{
		//if the block has a size more than or equal to 2048
		//then we cannot merge it into anything bigger so we just place it along with
		//2048 blocks and do not merge anything
		add_freelist_top(memBlock, 7);
		return;
	}
	else if (buddy->in_use || (buddy->size != memBlock->size))
	{
		//If the block's buddy is in use or if the block's size does not match with the buddy's size then
		//we do not merge them instead we just place the block at the correct index and return
		add_freelist_top(memBlock, freelist_index);
		return;
	}

	//Removing the ones we are merging from their original position in the free list
	while (buddy == freelist[freelist_index] || memBlock == freelist[freelist_index])
	{
		if(buddy == freelist[freelist_index])
		{
			remove_freelist_top(buddy, freelist_index);
			//buddy's next becomes NULL
		}
		if(memBlock == freelist[freelist_index])
		{
			remove_freelist_top(memBlock, freelist_index);
			//block's next becomes NULL
		}
	}

	//removing the block and buddy from their position in the linked list
	remove_from_freelist(memBlock);
	remove_from_freelist(buddy);

	if(memBlock > buddy)
	{
		buddy->size = buddy->size*2;
		merge_memBlock(buddy);
	}
	else
	{
		memBlock->size = memBlock->size*2;
		merge_memBlock(memBlock);
	}
}
Beispiel #3
0
void RosterManager::removeBuddy(const std::string &name) {
	Buddy *buddy = getBuddy(name);
	if (!buddy) {
		LOG4CXX_WARN(logger, m_user->getJID().toString() << ": Tried to remove unknown buddy " << name);
		return;
	}

	doRemoveBuddy(buddy);

	if (m_rosterStorage)
		m_rosterStorage->removeBuddy(buddy);

	unsetBuddy(buddy);
	delete buddy;
}
Beispiel #4
0
void RosterManager::handleSubscription(Swift::Presence::ref presence) {
	std::string legacyName = Buddy::JIDToLegacyName(presence->getTo(), m_user);
	if (legacyName.empty()) {
		return;
	}
	
	// For server mode the subscription changes are handler in rosterresponder.cpp
	// using roster pushes.
	if (m_component->inServerMode()) {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo(presence->getFrom().toBare());
		response->setFrom(presence->getTo().toBare());
		Buddy *buddy = getBuddy(legacyName);
		if (buddy) {
			LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received and buddy " << legacyName << " is already there => answering");
			switch (presence->getType()) {
				case Swift::Presence::Subscribe:
					onBuddyAdded(buddy);
					response->setType(Swift::Presence::Subscribed);
					break;
				case Swift::Presence::Unsubscribe:
					onBuddyRemoved(buddy);
					removeBuddy(buddy->getName());
					buddy = NULL;
					response->setType(Swift::Presence::Unsubscribed);
					break;
				case Swift::Presence::Subscribed:
					onBuddyAdded(buddy);
					break;
				default:
					return;
			}
			m_component->getFrontend()->sendPresence(response);
			
		}
		else {
			BuddyInfo buddyInfo;
			switch (presence->getType()) {
				// buddy is not in roster, so add him
				case Swift::Presence::Subscribe:
					buddyInfo.id = -1;
					buddyInfo.alias = "";
					buddyInfo.legacyName = legacyName;
					buddyInfo.subscription = "both";
					buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo());
					LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received for new buddy " << buddyInfo.legacyName << " => adding to legacy network");

					buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
					setBuddy(buddy);
					onBuddyAdded(buddy);
					response->setType(Swift::Presence::Subscribed);
					break;
				case Swift::Presence::Subscribed:
// 					onBuddyAdded(buddy);
					return;
				// buddy is not there, so nothing to do, just answer
				case Swift::Presence::Unsubscribe:
					buddyInfo.id = -1;
					buddyInfo.alias = "";
					buddyInfo.legacyName = legacyName;
					buddyInfo.subscription = "both";
					buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo());

					buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
					onBuddyRemoved(buddy);
					delete buddy;
					response->setType(Swift::Presence::Unsubscribed);
					break;
				default:
					return;
			}
			m_component->getFrontend()->sendPresence(response);
		}
	}
	else {
		Swift::Presence::ref response = Swift::Presence::create();
		Swift::Presence::ref currentPresence;
		response->setTo(presence->getFrom().toBare());
		response->setFrom(presence->getTo().toBare());

		Buddy *buddy = getBuddy(legacyName);
		if (buddy) {
			std::vector<Swift::Presence::ref> &presences = buddy->generatePresenceStanzas(255);
			switch (presence->getType()) {
				// buddy is already there, so nothing to do, just answer
				case Swift::Presence::Subscribe:
					onBuddyAdded(buddy);
					response->setType(Swift::Presence::Subscribed);
					BOOST_FOREACH(Swift::Presence::ref &currentPresence, presences) {
						currentPresence->setTo(presence->getFrom());
						m_component->getFrontend()->sendPresence(currentPresence);
					}
					if (buddy->getSubscription() != Buddy::Both) {
						buddy->setSubscription(Buddy::Both);
						storeBuddy(buddy);
					}
					break;
				// remove buddy
				case Swift::Presence::Unsubscribe:
					response->setType(Swift::Presence::Unsubscribed);
					onBuddyRemoved(buddy);
					removeBuddy(buddy->getName());
					buddy = NULL;
					break;
				// just send response
				case Swift::Presence::Unsubscribed:
					response->setType(Swift::Presence::Unsubscribe);
					// We set both here, because this Unsubscribed can be response to
					// subscribe presence and we don't want that unsubscribe presence
					// to be send later again
					if (buddy->getSubscription() != Buddy::Both) {
						buddy->setSubscription(Buddy::Both);
						storeBuddy(buddy);
					}
					break;
				case Swift::Presence::Subscribed:
					if (buddy->getSubscription() != Buddy::Both) {
						buddy->setSubscription(Buddy::Both);
						storeBuddy(buddy);
					}
					return;
				default:
					return;
			}
		}
		else {