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