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