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