<commit_before>#include <iostream>
#include <list>

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_list.hpp>

#include <libport/containers.hh>
#include <libport/finally.hh>

#include <runner/at-handler.hh>
#include <scheduler/tag.hh>

namespace runner
{

  class AtJob
  {
  public:
    AtJob(rObject condition, rObject clause, rObject on_leave,
	  scheduler::tags_type tags);
    bool blocked() const;
    bool frozen() const;
    const rObject& condition_get() const;
    const rObject& clause_get() const;
    const rObject& on_leave_get() const;
    bool triggered_get() const;
    void triggered_set(bool);
    const scheduler::tags_type& tags_get() const;
    bool tag_held(const scheduler::rTag& tag) const;
  private:
    rObject condition_;
    rObject clause_;
    rObject on_leave_;
    bool triggered_;
    scheduler::tags_type tags_;
  };

  class AtHandler : public Interpreter
  {
    typedef Interpreter super_type;
  public:
    AtHandler(const Interpreter&);
    virtual ~AtHandler();
    virtual void work();
    virtual bool frozen() const;
    void add_job(AtJob*);
    virtual void register_stopped_tag(const scheduler::rTag& tag,
				      boost::any);
  private:
    typedef boost::ptr_list<AtJob> at_jobs_type;
    at_jobs_type jobs_;
  };

  // There is only one at job handler. It will be created if it doesn't exist
  // and destroyed when it has no more jobs to handle.
  static AtHandler* at_job_handler;

  AtHandler::AtHandler(const Interpreter& model)
    : Interpreter(model,
		  object::rObject(0),
		  SYMBOL(LT_at_SP_jobs_SP_handler_GT))
  {
    // There are no reason to inherit tags from our creator, as this service
    // is not tied to any particular connection.
    tags_.clear();
  }

  AtHandler::~AtHandler()
  {
    jobs_.release();
  }

  void
  AtHandler::register_stopped_tag(const scheduler::rTag& tag, boost::any payload)
  {
    // If we are the current job, since we have no side effect, it must be
    // a flow control tag. Otherwise, remove all jobs holding this tag.
    if (scheduler_get().is_current_job(*this))
      super_type::register_stopped_tag(tag, payload);
    else
      jobs_.erase_if(boost::bind(&AtJob::tag_held, _1, tag));
  }

  void
  AtHandler::work()
  {
    while (true)
    {
      non_interruptible_set(true);

      for (at_jobs_type::iterator job = jobs_.begin();
	   job != jobs_.end();
	   /* Do not increment as we will also use erase() to advance */)
      {
	// If job has been frozen, we will not consider it for the moment.
	if (job->frozen())
	{
	  ++job;
	  continue;
	}

	// Check the job condition and continue if it has not changed.
	bool new_state;
	try
	{
	  new_state =
	    object::is_true(urbi_call(*this, job->condition_get(), SYMBOL(eval)),
			    SYMBOL(LT_at_SP_jobs_SP_handler_GT));
	}
	catch (const object::UrbiException& ue)
	{
	  show_error_(ue);
	  job = jobs_.erase(job);
	  continue;
	}
	catch (const kernel::exception& ke)
	{
	  std::cerr << "at condition triggered an exception: " << ke.what()
		    << std::endl;
	  job = jobs_.erase(job);
	  continue;
	}
	catch (...)
	{
	  std::cerr << "at condition triggered an exception\n";
	  job = jobs_.erase(job);<commit_msg>The non-interruptible status must be set no each job.<commit_after>#include <iostream>
#include <list>

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_list.hpp>

#include <libport/containers.hh>
#include <libport/finally.hh>

#include <runner/at-handler.hh>
#include <scheduler/tag.hh>

namespace runner
{

  class AtJob
  {
  public:
    AtJob(rObject condition, rObject clause, rObject on_leave,
	  scheduler::tags_type tags);
    bool blocked() const;
    bool frozen() const;
    const rObject& condition_get() const;
    const rObject& clause_get() const;
    const rObject& on_leave_get() const;
    bool triggered_get() const;
    void triggered_set(bool);
    const scheduler::tags_type& tags_get() const;
    bool tag_held(const scheduler::rTag& tag) const;
  private:
    rObject condition_;
    rObject clause_;
    rObject on_leave_;
    bool triggered_;
    scheduler::tags_type tags_;
  };

  class AtHandler : public Interpreter
  {
    typedef Interpreter super_type;
  public:
    AtHandler(const Interpreter&);
    virtual ~AtHandler();
    virtual void work();
    virtual bool frozen() const;
    void add_job(AtJob*);
    virtual void register_stopped_tag(const scheduler::rTag& tag,
				      boost::any);
  private:
    typedef boost::ptr_list<AtJob> at_jobs_type;
    at_jobs_type jobs_;
  };

  // There is only one at job handler. It will be created if it doesn't exist
  // and destroyed when it has no more jobs to handle.
  static AtHandler* at_job_handler;

  AtHandler::AtHandler(const Interpreter& model)
    : Interpreter(model,
		  object::rObject(0),
		  SYMBOL(LT_at_SP_jobs_SP_handler_GT))
  {
    // There are no reason to inherit tags from our creator, as this service
    // is not tied to any particular connection.
    tags_.clear();
  }

  AtHandler::~AtHandler()
  {
    jobs_.release();
  }

  void
  AtHandler::register_stopped_tag(const scheduler::rTag& tag, boost::any payload)
  {
    // If we are the current job, since we have no side effect, it must be
    // a flow control tag. Otherwise, remove all jobs holding this tag.
    if (scheduler_get().is_current_job(*this))
      super_type::register_stopped_tag(tag, payload);
    else
      jobs_.erase_if(boost::bind(&AtJob::tag_held, _1, tag));
  }

  void
  AtHandler::work()
  {
    while (true)
    {
      for (at_jobs_type::iterator job = jobs_.begin();
	   job != jobs_.end();
	   /* Do not increment as we will also use erase() to advance */)
      {
	// If job has been frozen, we will not consider it for the moment.
	if (job->frozen())
	{
	  ++job;
	  continue;
	}

	// Check the job condition and continue if it has not changed.
	bool new_state;
	try
	{
	  non_interruptible_set(true);
	  new_state =
	    object::is_true(urbi_call(*this, job->condition_get(), SYMBOL(eval)),
			    SYMBOL(LT_at_SP_jobs_SP_handler_GT));
	}
	catch (const object::UrbiException& ue)
	{
	  show_error_(ue);
	  job = jobs_.erase(job);
	  continue;
	}
	catch (const kernel::exception& ke)
	{
	  std::cerr << "at condition triggered an exception: " << ke.what()
		    << std::endl;
	  job = jobs_.erase(job);
	  continue;
	}
	catch (...)
	{
	  std::cerr << "at condition triggered an exception\n";
	  job = jobs_.erase(job);
{'fraction_non_alphanumeric': 0.11674968866749688, 'fraction_numerical': 0.0006226650062266501, 'mean_word_length': 3.4097460535346604, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 25, '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': '7626143', 'n_tokens_mistral': 2186, 'n_tokens_neox': 2109, 'n_words': 591}