<commit_before>#ifndef STINGRAYKIT_TASK_ALIVE_TOKEN_H
#define STINGRAYKIT_TASK_ALIVE_TOKEN_H


#include <stingraykit/thread/Thread.h>
#include <stingraykit/Final.h>
#include <stingraykit/self_counter.h>


namespace stingray
{

	/**
	 * @addtogroup toolkit_functions
	 * @{
	 */

	namespace Detail
	{
		struct TaskLifeTokenImpl : public self_counter<TaskLifeTokenImpl>
		{
		private:
			Mutex	_sync;
			bool	_alive;

		public:
			TaskLifeTokenImpl() : _alive(true)
			{}
			Mutex& GetMutex() 		{ return _sync; }
			bool IsAlive() const	{ return _alive; }
			void Kill()				{ _alive = false; }
		};
		STINGRAYKIT_DECLARE_SELF_COUNT_PTR(TaskLifeTokenImpl);
	};


	struct LocalExecutionGuard;
	struct FutureExecutionTester
	{
		friend struct LocalExecutionGuard;

	private:
		typedef Detail::TaskLifeTokenImplSelfCountPtr ImplPtr;
		ImplPtr _impl;

	public:
		FutureExecutionTester(const NullPtrType&) // always allows func execution
		{ }

		FutureExecutionTester(const Detail::TaskLifeTokenImplSelfCountPtr& impl) : _impl(impl)
		{ }
	};


	struct LocalExecutionGuard : public safe_bool<LocalExecutionGuard>
	{
		STINGRAYKIT_NONCOPYABLE(LocalExecutionGuard);

	private:
		bool									_allow;
		Detail::TaskLifeTokenImplSelfCountPtr	_impl;

	public:
		LocalExecutionGuard(const FutureExecutionTester& tester) : _allow(true), _impl(tester._impl)
		{
			if (!_impl)
				return;

			_impl->GetMutex().Lock();
			_allow = _impl->IsAlive();
			if (!_allow)
			{
				_impl->GetMutex().Unlock();
				_impl.reset();
			}
		}

		~LocalExecutionGuard()
		{
			if (_impl)
				_impl->GetMutex().Unlock();
		}

		bool boolean_test() const
		{ return _allow; }
	};


	class TaskLifeToken : STINGRAYKIT_FINAL(TaskLifeToken)
	{
	private:
		Detail::TaskLifeTokenImplSelfCountPtr _impl;

	public:
		TaskLifeToken() : _impl(new Detail::TaskLifeTokenImpl)
		{}

		~TaskLifeToken()
		{}

		void Release()
		{
			MutexLock l(_impl->GetMutex());
			_impl->Kill();
		}

		TaskLifeToken& Reset()
		{
			Release();
			return (*this = TaskLifeToken());
		}

		FutureExecutionTester GetExecutionTester() const
		{ return FutureExecutionTester(_impl); }
	};
	STINGRAYKIT_DECLARE_PTR(TaskLifeToken);

	/** @} */

}


#endif<commit_msg>Reimplemented TaskLifeToken<commit_after>#ifndef STINGRAYKIT_TASK_ALIVE_TOKEN_H
#define STINGRAYKIT_TASK_ALIVE_TOKEN_H


#include <stingraykit/thread/Thread.h>
#include <stingraykit/Final.h>
#include <stingraykit/self_counter.h>


namespace stingray
{

	/**
	 * @addtogroup toolkit_functions
	 * @{
	 */

	namespace Detail
	{
		struct TaskLifeTokenImpl : public self_counter<TaskLifeTokenImpl>
		{
		private:
			Mutex	_sync;
			bool	_alive;

		public:
			TaskLifeTokenImpl() : _alive(true)
			{ }

			bool TryStartExecution()
			{
				_sync.Lock();
				if (_alive)
					return true;
				_sync.Unlock();
				return false;
			}

			void FinishExecution()
			{ _sync.Unlock(); }

			void Kill()
			{
				MutexLock l(_sync);
				_alive = false;
			}
		};
		STINGRAYKIT_DECLARE_SELF_COUNT_PTR(TaskLifeTokenImpl);
	};


	struct LocalExecutionGuard;
	struct FutureExecutionTester
	{
		friend struct LocalExecutionGuard;

	private:
		typedef Detail::TaskLifeTokenImplSelfCountPtr ImplPtr;
		ImplPtr _impl;

	public:
		FutureExecutionTester(const NullPtrType&) // always allows func execution
		{ }

		FutureExecutionTester(const Detail::TaskLifeTokenImplSelfCountPtr& impl) : _impl(impl)
		{ }
	};


	struct LocalExecutionGuard : public safe_bool<LocalExecutionGuard>
	{
		STINGRAYKIT_NONCOPYABLE(LocalExecutionGuard);

	private:
		bool									_allow;
		Detail::TaskLifeTokenImplSelfCountPtr	_impl;

	public:
		LocalExecutionGuard(const FutureExecutionTester& tester) : _allow(true), _impl(tester._impl)
		{
			if (!_impl)
				return;
			_allow = _impl->TryStartExecution();
			if (!_allow)
				_impl.reset();
		}

		~LocalExecutionGuard()
		{
			if (_impl)
				_impl->FinishExecution();
		}

		bool boolean_test() const
		{ return _allow; }
	};


	class TaskLifeToken : STINGRAYKIT_FINAL(TaskLifeToken)
	{
	private:
		Detail::TaskLifeTokenImplSelfCountPtr _impl;

	public:
		TaskLifeToken() : _impl(new Detail::TaskLifeTokenImpl)
		{ }

		~TaskLifeToken()
		{ }

		void Release()
		{
			_impl->Kill();
		}

		TaskLifeToken& Reset()
		{
			Release();
			return (*this = TaskLifeToken());
		}

		FutureExecutionTester GetExecutionTester() const
		{ return FutureExecutionTester(_impl); }
	};
	STINGRAYKIT_DECLARE_PTR(TaskLifeToken);

	/** @} */

}


#endif
{'fraction_non_alphanumeric': 0.11278364412491575, 'fraction_numerical': 0.0, 'mean_word_length': 4.064846416382252, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3197844', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1566, 'n_words': 262}