status_t
MessagingService::UnregisterService()
{
	// check, if the team calling this function is indeed the server team
	thread_info threadInfo;
	status_t error = get_thread_info(find_thread(NULL), &threadInfo);
	if (error != B_OK)
		return error;

	if (threadInfo.team != fServerTeam)
		return B_BAD_VALUE;

	// delete all areas
	while (fFirstArea) {
		MessagingArea *area = fFirstArea;
		fFirstArea = area->NextArea();
		delete area;
	}
	fLastArea = NULL;

	// unset the other members
	fLockSem = -1;
	fCounterSem = -1;
	fServerTeam = -1;

	return B_OK;
}
// _CommandProcessor
int32
MessagingService::_CommandProcessor()
{
	bool commandWaiting = false;
	while (!fTerminating) {
		// wait for the next command
		if (!commandWaiting) {
			status_t error = acquire_sem(fCounterSem);
			if (error != B_OK)
				continue;
		} else
			commandWaiting = false;

		// get it from the first area
		MessagingArea *area = fFirstArea;
		area->Lock();
		while (area->CountCommands() > 0) {
			const messaging_command *command = area->PopCommand();
			if (!command) {
				// something's seriously wrong
				ERROR("MessagingService::_CommandProcessor(): area %p (%"
					B_PRId32 ") has command count %" B_PRId32 ", but doesn't "
					"return any more commands.", area, area->ID(),
					area->CountCommands());
				break;
			}
PRINT("MessagingService::_CommandProcessor(): got command %" B_PRIu32 "\n",
command->command);

			// dispatch the command
			MessagingCommandHandler *handler
				= _GetCommandHandler(command->command);
			if (handler) {
				handler->HandleMessagingCommand(command->command, command->data,
					command->size - sizeof(messaging_command));
			} else {
				WARNING("MessagingService::_CommandProcessor(): No handler "
					"found for command %" B_PRIu32 "\n", command->command);
			}
		}

		// there is a new area we don't know yet
		if (!area->NextArea() && area->NextKernelAreaID() >= 0) {
			// create it
			MessagingArea *nextArea;
			status_t error = MessagingArea::Create(area->NextKernelAreaID(),
				fLockSem, fCounterSem, nextArea);
			if (error == B_OK) {
				area->SetNextArea(nextArea);
				commandWaiting = true;
			} else {
				// Bad, but what can we do?
				ERROR("MessagingService::_CommandProcessor(): Failed to clone "
					"kernel area %" B_PRId32 ": %s\n", area->NextKernelAreaID(),
					strerror(error));
			}

		}

		// if the current area is empty and there is a next one, we discard the
		// current one
		if (area->NextArea() && area->CountCommands() == 0) {
			fFirstArea = area->NextArea();
			area->Discard();
			area->Unlock();
			delete area;
		} else {
			area->Unlock();
		}
	}

	return 0;
}