#pragma once

#include "NonCopyable.h"
#include "../os/Atomic.h"
#include "../os/Mutex.h"

namespace il2cpp
{
namespace utils
{

typedef void (*CallOnceFunc) (void* arg);

struct OnceFlag : NonCopyable
{
	OnceFlag () : m_Flag (NULL)
	{
	}

	friend void CallOnce (OnceFlag& flag, CallOnceFunc func, void* arg);

private:
	void* m_Flag;
	il2cpp::os::FastMutex m_Mutex;
};

inline void CallOnce (OnceFlag& flag, CallOnceFunc func, void* arg)
{
	if (!il2cpp::os::Atomic::ReadPointer (&flag.m_Flag))
	{
		os::FastAutoLock lock (&flag.m_Mutex);
		if (!il2cpp::os::Atomic::ReadPointer (&flag.m_Flag))
		{
			func (arg);
			il2cpp::os::Atomic::ExchangePointer (&flag.m_Flag, (void*)1);
		}
	}
}

}
}
