1e254a845SShuo Chen// excerpts from http://code.google.com/p/muduo/
2e254a845SShuo Chen//
3e254a845SShuo Chen// Use of this source code is governed by a BSD-style license
4e254a845SShuo Chen// that can be found in the License file.
5e254a845SShuo Chen//
6e254a845SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
7e254a845SShuo Chen
8e254a845SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
9e254a845SShuo Chen#define MUDUO_NET_EVENTLOOP_H
10e254a845SShuo Chen
11e254a845SShuo Chen#include "datetime/Timestamp.h"
12e254a845SShuo Chen#include "thread/Mutex.h"
13e254a845SShuo Chen#include "thread/Thread.h"
14e254a845SShuo Chen#include "Callbacks.h"
15e254a845SShuo Chen#include "TimerId.h"
16e254a845SShuo Chen
17e254a845SShuo Chen#include <boost/scoped_ptr.hpp>
18e254a845SShuo Chen#include <vector>
19e254a845SShuo Chen
20e254a845SShuo Chennamespace muduo
21e254a845SShuo Chen{
22e254a845SShuo Chen
23e254a845SShuo Chenclass Channel;
24e254a845SShuo Chenclass Poller;
25e254a845SShuo Chenclass TimerQueue;
26e254a845SShuo Chen
27e254a845SShuo Chenclass EventLoop : boost::noncopyable
28e254a845SShuo Chen{
29e254a845SShuo Chen public:
30e254a845SShuo Chen  typedef boost::function<void()> Functor;
31e254a845SShuo Chen
32e254a845SShuo Chen  EventLoop();
33e254a845SShuo Chen
34e254a845SShuo Chen  // force out-line dtor, for scoped_ptr members.
35e254a845SShuo Chen  ~EventLoop();
36e254a845SShuo Chen
37e254a845SShuo Chen  ///
38e254a845SShuo Chen  /// Loops forever.
39e254a845SShuo Chen  ///
40e254a845SShuo Chen  /// Must be called in the same thread as creation of the object.
41e254a845SShuo Chen  ///
42e254a845SShuo Chen  void loop();
43e254a845SShuo Chen
44e254a845SShuo Chen  void quit();
45e254a845SShuo Chen
46e254a845SShuo Chen  ///
47e254a845SShuo Chen  /// Time when poll returns, usually means data arrivial.
48e254a845SShuo Chen  ///
49e254a845SShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
50e254a845SShuo Chen
51e254a845SShuo Chen  /// Runs callback immediately in the loop thread.
52e254a845SShuo Chen  /// It wakes up the loop, and run the cb.
53e254a845SShuo Chen  /// If in the same loop thread, cb is run within the function.
54e254a845SShuo Chen  /// Safe to call from other threads.
55e254a845SShuo Chen  void runInLoop(const Functor& cb);
56e254a845SShuo Chen  /// Queues callback in the loop thread.
57e254a845SShuo Chen  /// Runs after finish pooling.
58e254a845SShuo Chen  /// Safe to call from other threads.
59e254a845SShuo Chen  void queueInLoop(const Functor& cb);
60e254a845SShuo Chen
61e254a845SShuo Chen  // timers
62e254a845SShuo Chen
63e254a845SShuo Chen  ///
64e254a845SShuo Chen  /// Runs callback at 'time'.
65e254a845SShuo Chen  /// Safe to call from other threads.
66e254a845SShuo Chen  ///
67e254a845SShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
68e254a845SShuo Chen  ///
69e254a845SShuo Chen  /// Runs callback after @c delay seconds.
70e254a845SShuo Chen  /// Safe to call from other threads.
71e254a845SShuo Chen  ///
72e254a845SShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
73e254a845SShuo Chen  ///
74e254a845SShuo Chen  /// Runs callback every @c interval seconds.
75e254a845SShuo Chen  /// Safe to call from other threads.
76e254a845SShuo Chen  ///
77e254a845SShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
78e254a845SShuo Chen
79e254a845SShuo Chen  // void cancel(TimerId timerId);
80e254a845SShuo Chen
81e254a845SShuo Chen  // internal use only
82e254a845SShuo Chen  void wakeup();
83e254a845SShuo Chen  void updateChannel(Channel* channel);
84e254a845SShuo Chen  void removeChannel(Channel* channel);
85e254a845SShuo Chen
86e254a845SShuo Chen  void assertInLoopThread()
87e254a845SShuo Chen  {
88e254a845SShuo Chen    if (!isInLoopThread())
89e254a845SShuo Chen    {
90e254a845SShuo Chen      abortNotInLoopThread();
91e254a845SShuo Chen    }
92e254a845SShuo Chen  }
93e254a845SShuo Chen
94e254a845SShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
95e254a845SShuo Chen
96e254a845SShuo Chen private:
97e254a845SShuo Chen
98e254a845SShuo Chen  void abortNotInLoopThread();
99e254a845SShuo Chen  void handleRead();  // waked up
100e254a845SShuo Chen  void doPendingFunctors();
101e254a845SShuo Chen
102e254a845SShuo Chen  typedef std::vector<Channel*> ChannelList;
103e254a845SShuo Chen
104e254a845SShuo Chen  bool looping_; /* atomic */
105e254a845SShuo Chen  bool quit_; /* atomic */
106e254a845SShuo Chen  bool callingPendingFunctors_; /* atomic */
107e254a845SShuo Chen  const pid_t threadId_;
108e254a845SShuo Chen  Timestamp pollReturnTime_;
109e254a845SShuo Chen  boost::scoped_ptr<Poller> poller_;
110e254a845SShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
111e254a845SShuo Chen  int wakeupFd_;
112e254a845SShuo Chen  // unlike in TimerQueue, which is an internal class,
113e254a845SShuo Chen  // we don't expose Channel to client.
114e254a845SShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
115e254a845SShuo Chen  ChannelList activeChannels_;
116e254a845SShuo Chen  MutexLock mutex_;
117fd65b0afSShuo Chen  std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_
118e254a845SShuo Chen};
119e254a845SShuo Chen
120e254a845SShuo Chen}
121e254a845SShuo Chen
122e254a845SShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123