/*
 * cleaner.cc
 *
 *  Created on: 05.02.2011
 *      Author: ed
 */

#include "debug.h"
#include "meta.h"

#include "cleaner.h"

#include "fileitem.h"
#include "acfg.h"
#include "caddrinfo.h"
#include "tcpconnect.h"

#include <limits>
#include <cstring>
using namespace MYSTD;

cleaner g_victor;

const time_t cleaner::never = numeric_limits<time_t>::max();

cleaner::cleaner() : m_bAssigned(false), m_bAwaken(false)
{
}


enum { fiStart, hookStart, dnsStart, cpoolStart, _sched_name_max};

time_t scheds[_sched_name_max];

void cleaner::Do()
{
	LOGSTART("cleaner::Do");

	{ // make sure that it runs exclusively
		setLockGuard;
		if(m_bAssigned)
		{
			// ok, there is no work for us but make sure that the responsible threads awakes soon
			// in order to check the changed situation
			m_bAwaken=true;
			notifyAll();
			return;
		}
		m_bAssigned=true;
		memset(&scheds, 0, sizeof(scheds));
	}

	for(;;)
	{
		{
			setLockGuard;
			if(m_bAwaken) // forced by another thread, check work schedules
			{
				memset(&scheds, 0, sizeof(scheds));
				m_bAwaken=false;
			}
		}

		time_t now(time(0));

		if(scheds[fiStart] <= now)
			scheds[fiStart]=fileitem::DoDelayedUnregAndCheck();

		if(scheds[hookStart] <= now)
			scheds[hookStart] = acfg::ExecutePostponed();

		if(scheds[dnsStart] <=now)
			scheds[dnsStart] = CAddrInfo::ExpireCache();

		if(scheds[cpoolStart] <=now)
			scheds[cpoolStart] = tcpconnect::ExpireCache();

		{
			setLockGuard;

			// someone sent a work command? don't sleep then
			if(m_bAwaken)
				continue;

			time_t wakeTime = never;
			for(UINT i=0; i<_countof(scheds); i++)
			{
				if(scheds[i]<wakeTime)
					wakeTime=scheds[i];
			}

			if(never == wakeTime) // unreachable, finish the thread now, another requester will continue later
			{
				m_bAssigned=false;
				return;
			}

			wait(max(wakeTime-now, time_t(1)), 786);
		}

		ldbg("time over");
	};

	setLockGuard;
	m_bAssigned=false;
}

cleaner::~cleaner()
{
	// TODO Auto-generated destructor stub
}
