Home | History | Annotate | Download | only in provider
      1 // Copyright 2015 The Weave Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_
      6 #define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_
      7 
      8 #include <queue>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include <event2/event.h>
     13 #include <weave/provider/task_runner.h>
     14 
     15 #include "examples/provider/event_deleter.h"
     16 
     17 namespace weave {
     18 namespace examples {
     19 
     20 // Simple task runner implemented with libevent message loop.
     21 class EventTaskRunner : public provider::TaskRunner {
     22  public:
     23   void PostDelayedTask(const tracked_objects::Location& from_here,
     24                        const base::Closure& task,
     25                        base::TimeDelta delay) override;
     26 
     27   // Defines the types of I/O completion events that the
     28   // application can register to receive on a file descriptor.
     29   enum IOEvent : int16_t {
     30     kReadable = 0x01,
     31     kWriteable = 0x02,
     32     kClosed = 0x04,
     33     kReadableWriteable = kReadable | kWriteable,
     34     kReadableOrClosed = kReadable | kClosed,
     35     kAll = kReadableOrClosed | kWriteable,
     36   };
     37 
     38   // Callback type for I/O completion events.
     39   // Arguments:
     40   //  fd -      file descriptor that triggered the event
     41   //  what -    combination of IOEvent flags indicating
     42   //            which event(s) occurred
     43   //  sender -  reference to the EventTaskRunner that
     44   //            called the IoCompletionCallback
     45   using IoCompletionCallback =
     46       base::Callback<void(int fd, int16_t what, EventTaskRunner* sender)>;
     47 
     48   // Adds a handler for the specified IO completion events on a file
     49   // descriptor. The 'what' parameter is a combination of IOEvent flags.
     50   // Only one callback is allowed per file descriptor; calling this function
     51   // with an fd that has already been registered will replace the previous
     52   // callback with the new one.
     53   void AddIoCompletionTask(int fd,
     54                            int16_t what,
     55                            const IoCompletionCallback& task);
     56 
     57   // Remove the callback associated with this fd and stop listening for
     58   // events related to it.
     59   void RemoveIoCompletionTask(int fd);
     60 
     61   event_base* GetEventBase() const { return base_.get(); }
     62 
     63   void Run();
     64 
     65  private:
     66   void ReScheduleEvent(base::TimeDelta delay);
     67   static void EventHandler(int, int16_t, void* runner);
     68   static void FreeEvent(event* evnt);
     69   void Process();
     70 
     71   static void FdEventHandler(int fd, int16_t what, void* runner);
     72   void ProcessFd(int fd, int16_t what);
     73 
     74   using QueueItem = std::pair<std::pair<base::Time, size_t>, base::Closure>;
     75 
     76   struct Greater {
     77     bool operator()(const QueueItem& a, const QueueItem& b) const {
     78       return a.first > b.first;
     79     }
     80   };
     81 
     82   size_t counter_{0};  // Keeps order of tasks with the same time.
     83 
     84   std::priority_queue<QueueItem,
     85                       std::vector<QueueItem>,
     86                       EventTaskRunner::Greater>
     87       queue_;
     88 
     89   EventPtr<event_base> base_{event_base_new()};
     90 
     91   EventPtr<event> task_event_{
     92       event_new(base_.get(), -1, EV_TIMEOUT, &EventHandler, this)};
     93 
     94   std::map<int, std::pair<EventPtr<event>, IoCompletionCallback>> fd_task_map_;
     95 };
     96 
     97 }  // namespace examples
     98 }  // namespace weave
     99 
    100 #endif  // LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_
    101