Program Listing for File tasklet.h

Return to documentation for file (liberate/concurrency/tasklet.h)

/*
 * This file is part of liberate.
 *
 * Author(s): Jens Finkhaeuser <jens@finkhaeuser.de>
 *
 * Copyright (c) 2014 Unwesen Ltd.
 * Copyright (c) 2015-2021 Jens Finkhaeuser.
 * Copyright (c) 2022 Interpeer gUG (haftungsbeschränkt)
 *
 * SPDX-License-Identifier: GPL-3.0-only
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBERATE_CONCURRENCY_TASKLET_H
#define LIBERATE_CONCURRENCY_TASKLET_H

#ifndef __cplusplus
#error You are trying to include a C++ only header file
#endif

#include <liberate.h>

#include <atomic>
#include <mutex>
#include <condition_variable>
#include <functional>

namespace liberate::concurrency {

class LIBERATE_API tasklet
{
public:
  /***************************************************************************
   * Types
   **/
  struct LIBERATE_API sleep_condition
  {
    std::condition_variable condition;
    std::mutex              mutex;
  };

  struct LIBERATE_API context
  {
    std::atomic<bool>   running;

    sleep_condition *   condition;

    explicit context(sleep_condition * condition);

    virtual ~context();

    template <typename durationT>
    inline bool sleep(durationT const & duration) const
    {
      return context::nanosleep(std::chrono::round<std::chrono::nanoseconds>(duration));
    }

    inline bool sleep() const
    {
      return context::nanosleep(std::chrono::nanoseconds(-1));
    }

  private:
    /***************************************************************************
     * Implementation functions
     **/
    bool nanosleep(std::chrono::nanoseconds nsecs) const;
  };

  using task_function = std::function<void (context &)>;


  /***************************************************************************
   * Constructor/destructor
   **/
  explicit tasklet(task_function && func, bool start_now = false);

  tasklet(task_function && func, sleep_condition * condition,
      bool start_now = false);

  ~tasklet();

  /***************************************************************************
   * Main interface
   **/
  bool start();

  bool stop();

  void wait();

  void wakeup();

private:
  tasklet(tasklet const &) = delete;
  tasklet(tasklet &&) = delete;
  tasklet & operator=(tasklet const &) = delete;

  /***************************************************************************
   * Data
   **/
  mutable std::unique_ptr<context> m_context;
};

} // namespace liberate::concurrency


#endif // guard