예제 #1
0
파일: IMAPMailbox.cpp 프로젝트: DonCN/haiku
status_t
IMAPMailbox::StartWatchingMailbox(sem_id startedSem)
{
	atomic_set(&fWatching, 1);

	bool firstIDLE = true;
	// refresh every 29 min
	bigtime_t timeout = 1000 * 1000 * 60 * 29; // 29 min
	status_t status;
	while (true) {
		int32 commandID = NextCommandID();
		TRACE("IDLE ...\n");
		status = SendCommand("IDLE", commandID);
		if (firstIDLE) {
			release_sem(startedSem);
			firstIDLE = false;
		}
		if (status != B_OK)
			break;

		status = HandleResponse(commandID, timeout, false);
		ProcessAfterQuacks(kIMAP4ClientTimeout);

		if (atomic_get(&fWatching) == 0)
			break;

		if (status == B_TIMED_OUT) {
			TRACE("Renew IDLE connection.\n");
			status = SendRawCommand("DONE");
			if (status != B_OK)
				break;
			// handle IDLE response and more
			status = ProcessCommand("NOOP");
			if (status != B_OK)
				break;
			else
				continue;
		}
		if (status != B_OK)
			break;
	}

	atomic_set(&fWatching, 0);
	return status;
}
예제 #2
0
status_t
Protocol::ProcessCommand(Command& command, bigtime_t timeout)
{
	BString commandString = command.CommandString();
	if (commandString.IsEmpty())
		return B_BAD_VALUE;

	Handler* handler = dynamic_cast<Handler*>(&command);
	if (handler != NULL && !AddHandler(*handler))
		return B_NO_MEMORY;

	int32 commandID = NextCommandID();
	status_t status = SendCommand(commandID, commandString.String());
	if (status == B_OK) {
		fOngoingCommands[commandID] = &command;
		status = HandleResponse(&command, timeout);
	}

	if (handler != NULL)
		RemoveHandler(*handler);

	return status;
}