EventLoop.h revision 354280cf
1354280cfSShuo Chen// excerpts from http://code.google.com/p/muduo/
2354280cfSShuo Chen//
3354280cfSShuo Chen// Use of this source code is governed by a BSD-style license
4354280cfSShuo Chen// that can be found in the License file.
5354280cfSShuo Chen//
6354280cfSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
7354280cfSShuo Chen
8354280cfSShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
9354280cfSShuo Chen#define MUDUO_NET_EVENTLOOP_H
10354280cfSShuo Chen
11354280cfSShuo Chen#include "datetime/Timestamp.h"
12354280cfSShuo Chen#include "thread/Mutex.h"
13354280cfSShuo Chen#include "thread/Thread.h"
14354280cfSShuo Chen#include "Callbacks.h"
15354280cfSShuo Chen#include "TimerId.h"
16354280cfSShuo Chen
17354280cfSShuo Chen#include <boost/scoped_ptr.hpp>
18354280cfSShuo Chen#include <vector>
19354280cfSShuo Chen
20354280cfSShuo Chennamespace muduo
21354280cfSShuo Chen{
22354280cfSShuo Chen
23354280cfSShuo Chenclass Channel;
24354280cfSShuo Chenclass Poller;
25354280cfSShuo Chenclass TimerQueue;
26354280cfSShuo Chen
27354280cfSShuo Chenclass EventLoop : boost::noncopyable
28354280cfSShuo Chen{
29354280cfSShuo Chen public:
30354280cfSShuo Chen  typedef boost::function<void()> Functor;
31354280cfSShuo Chen
32354280cfSShuo Chen  EventLoop();
33354280cfSShuo Chen
34354280cfSShuo Chen  // force out-line dtor, for scoped_ptr members.
35354280cfSShuo Chen  ~EventLoop();
36354280cfSShuo Chen
37354280cfSShuo Chen  ///
38354280cfSShuo Chen  /// Loops forever.
39354280cfSShuo Chen  ///
40354280cfSShuo Chen  /// Must be called in the same thread as creation of the object.
41354280cfSShuo Chen  ///
42354280cfSShuo Chen  void loop();
43354280cfSShuo Chen
44354280cfSShuo Chen  void quit();
45354280cfSShuo Chen
46354280cfSShuo Chen  ///
47354280cfSShuo Chen  /// Time when poll returns, usually means data arrivial.
48354280cfSShuo Chen  ///
49354280cfSShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
50354280cfSShuo Chen
51354280cfSShuo Chen  /// Runs callback immediately in the loop thread.
52354280cfSShuo Chen  /// It wakes up the loop, and run the cb.
53354280cfSShuo Chen  /// If in the same loop thread, cb is run within the function.
54354280cfSShuo Chen  /// Safe to call from other threads.
55354280cfSShuo Chen  void runInLoop(const Functor& cb);
56354280cfSShuo Chen  /// Queues callback in the loop thread.
57354280cfSShuo Chen  /// Runs after finish pooling.
58354280cfSShuo Chen  /// Safe to call from other threads.
59354280cfSShuo Chen  void queueInLoop(const Functor& cb);
60354280cfSShuo Chen
61354280cfSShuo Chen  // timers
62354280cfSShuo Chen
63354280cfSShuo Chen  ///
64354280cfSShuo Chen  /// Runs callback at 'time'.
65354280cfSShuo Chen  /// Safe to call from other threads.
66354280cfSShuo Chen  ///
67354280cfSShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
68354280cfSShuo Chen  ///
69354280cfSShuo Chen  /// Runs callback after @c delay seconds.
70354280cfSShuo Chen  /// Safe to call from other threads.
71354280cfSShuo Chen  ///
72354280cfSShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
73354280cfSShuo Chen  ///
74354280cfSShuo Chen  /// Runs callback every @c interval seconds.
75354280cfSShuo Chen  /// Safe to call from other threads.
76354280cfSShuo Chen  ///
77354280cfSShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
78354280cfSShuo Chen
79354280cfSShuo Chen  void cancel(TimerId timerId);
80354280cfSShuo Chen
81354280cfSShuo Chen  // internal use only
82354280cfSShuo Chen  void wakeup();
83354280cfSShuo Chen  void updateChannel(Channel* channel);
84354280cfSShuo Chen  void removeChannel(Channel* channel);
85354280cfSShuo Chen
86354280cfSShuo Chen  void assertInLoopThread()
87354280cfSShuo Chen  {
88354280cfSShuo Chen    if (!isInLoopThread())
89354280cfSShuo Chen    {
90354280cfSShuo Chen      abortNotInLoopThread();
91354280cfSShuo Chen    }
92354280cfSShuo Chen  }
93354280cfSShuo Chen
94354280cfSShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
95354280cfSShuo Chen
96354280cfSShuo Chen private:
97354280cfSShuo Chen
98354280cfSShuo Chen  void abortNotInLoopThread();
99354280cfSShuo Chen  void handleRead();  // waked up
100354280cfSShuo Chen  void doPendingFunctors();
101354280cfSShuo Chen
102354280cfSShuo Chen  typedef std::vector<Channel*> ChannelList;
103354280cfSShuo Chen
104354280cfSShuo Chen  bool looping_; /* atomic */
105354280cfSShuo Chen  bool quit_; /* atomic */
106354280cfSShuo Chen  bool callingPendingFunctors_; /* atomic */
107354280cfSShuo Chen  const pid_t threadId_;
108354280cfSShuo Chen  Timestamp pollReturnTime_;
109354280cfSShuo Chen  boost::scoped_ptr<Poller> poller_;
110354280cfSShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
111354280cfSShuo Chen  int wakeupFd_;
112354280cfSShuo Chen  // unlike in TimerQueue, which is an internal class,
113354280cfSShuo Chen  // we don't expose Channel to client.
114354280cfSShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
115354280cfSShuo Chen  ChannelList activeChannels_;
116354280cfSShuo Chen  MutexLock mutex_;
117354280cfSShuo Chen  std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_
118354280cfSShuo Chen};
119354280cfSShuo Chen
120354280cfSShuo Chen}
121354280cfSShuo Chen
122354280cfSShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123