140161064SShuo Chen// excerpts from http://code.google.com/p/muduo/
240161064SShuo Chen//
340161064SShuo Chen// Use of this source code is governed by a BSD-style license
440161064SShuo Chen// that can be found in the License file.
540161064SShuo Chen//
640161064SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
740161064SShuo Chen
840161064SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
940161064SShuo Chen#define MUDUO_NET_EVENTLOOP_H
1040161064SShuo Chen
1140161064SShuo Chen#include "datetime/Timestamp.h"
1240161064SShuo Chen#include "thread/Mutex.h"
1340161064SShuo Chen#include "thread/Thread.h"
1440161064SShuo Chen#include "Callbacks.h"
1540161064SShuo Chen#include "TimerId.h"
1640161064SShuo Chen
1740161064SShuo Chen#include <boost/scoped_ptr.hpp>
1840161064SShuo Chen#include <vector>
1940161064SShuo Chen
2040161064SShuo Chennamespace muduo
2140161064SShuo Chen{
2240161064SShuo Chen
2340161064SShuo Chenclass Channel;
2440161064SShuo Chenclass Poller;
2540161064SShuo Chenclass TimerQueue;
2640161064SShuo Chen
2740161064SShuo Chenclass EventLoop : boost::noncopyable
2840161064SShuo Chen{
2940161064SShuo Chen public:
3040161064SShuo Chen  typedef boost::function<void()> Functor;
3140161064SShuo Chen
3240161064SShuo Chen  EventLoop();
3340161064SShuo Chen
3440161064SShuo Chen  // force out-line dtor, for scoped_ptr members.
3540161064SShuo Chen  ~EventLoop();
3640161064SShuo Chen
3740161064SShuo Chen  ///
3840161064SShuo Chen  /// Loops forever.
3940161064SShuo Chen  ///
4040161064SShuo Chen  /// Must be called in the same thread as creation of the object.
4140161064SShuo Chen  ///
4240161064SShuo Chen  void loop();
4340161064SShuo Chen
4440161064SShuo Chen  void quit();
4540161064SShuo Chen
4640161064SShuo Chen  ///
4740161064SShuo Chen  /// Time when poll returns, usually means data arrivial.
4840161064SShuo Chen  ///
4940161064SShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
5040161064SShuo Chen
5140161064SShuo Chen  /// Runs callback immediately in the loop thread.
5240161064SShuo Chen  /// It wakes up the loop, and run the cb.
5340161064SShuo Chen  /// If in the same loop thread, cb is run within the function.
5440161064SShuo Chen  /// Safe to call from other threads.
5540161064SShuo Chen  void runInLoop(const Functor& cb);
5640161064SShuo Chen  /// Queues callback in the loop thread.
5740161064SShuo Chen  /// Runs after finish pooling.
5840161064SShuo Chen  /// Safe to call from other threads.
5940161064SShuo Chen  void queueInLoop(const Functor& cb);
6040161064SShuo Chen
6140161064SShuo Chen  // timers
6240161064SShuo Chen
6340161064SShuo Chen  ///
6440161064SShuo Chen  /// Runs callback at 'time'.
6540161064SShuo Chen  /// Safe to call from other threads.
6640161064SShuo Chen  ///
6740161064SShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
6840161064SShuo Chen  ///
6940161064SShuo Chen  /// Runs callback after @c delay seconds.
7040161064SShuo Chen  /// Safe to call from other threads.
7140161064SShuo Chen  ///
7240161064SShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
7340161064SShuo Chen  ///
7440161064SShuo Chen  /// Runs callback every @c interval seconds.
7540161064SShuo Chen  /// Safe to call from other threads.
7640161064SShuo Chen  ///
7740161064SShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
7840161064SShuo Chen
79f4e8e3d3SShuo Chen  void cancel(TimerId timerId);
8040161064SShuo Chen
8140161064SShuo Chen  // internal use only
8240161064SShuo Chen  void wakeup();
8340161064SShuo Chen  void updateChannel(Channel* channel);
8440161064SShuo Chen  void removeChannel(Channel* channel);
8540161064SShuo Chen
8640161064SShuo Chen  void assertInLoopThread()
8740161064SShuo Chen  {
8840161064SShuo Chen    if (!isInLoopThread())
8940161064SShuo Chen    {
9040161064SShuo Chen      abortNotInLoopThread();
9140161064SShuo Chen    }
9240161064SShuo Chen  }
9340161064SShuo Chen
9440161064SShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
9540161064SShuo Chen
9640161064SShuo Chen private:
9740161064SShuo Chen
9840161064SShuo Chen  void abortNotInLoopThread();
9940161064SShuo Chen  void handleRead();  // waked up
10040161064SShuo Chen  void doPendingFunctors();
10140161064SShuo Chen
10240161064SShuo Chen  typedef std::vector<Channel*> ChannelList;
10340161064SShuo Chen
10440161064SShuo Chen  bool looping_; /* atomic */
10540161064SShuo Chen  bool quit_; /* atomic */
10640161064SShuo Chen  bool callingPendingFunctors_; /* atomic */
10740161064SShuo Chen  const pid_t threadId_;
10840161064SShuo Chen  Timestamp pollReturnTime_;
10940161064SShuo Chen  boost::scoped_ptr<Poller> poller_;
11040161064SShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
11140161064SShuo Chen  int wakeupFd_;
11240161064SShuo Chen  // unlike in TimerQueue, which is an internal class,
11340161064SShuo Chen  // we don't expose Channel to client.
11440161064SShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
11540161064SShuo Chen  ChannelList activeChannels_;
11640161064SShuo Chen  MutexLock mutex_;
11740161064SShuo Chen  std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_
11840161064SShuo Chen};
11940161064SShuo Chen
12040161064SShuo Chen}
12140161064SShuo Chen
12240161064SShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123