12745a763SShuo Chen// excerpts from http://code.google.com/p/muduo/
22745a763SShuo Chen//
32745a763SShuo Chen// Use of this source code is governed by a BSD-style license
42745a763SShuo Chen// that can be found in the License file.
52745a763SShuo Chen//
62745a763SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
72745a763SShuo Chen
82745a763SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
92745a763SShuo Chen#define MUDUO_NET_EVENTLOOP_H
102745a763SShuo Chen
112745a763SShuo Chen#include "datetime/Timestamp.h"
122745a763SShuo Chen#include "thread/Mutex.h"
132745a763SShuo Chen#include "thread/Thread.h"
142745a763SShuo Chen#include "Callbacks.h"
152745a763SShuo Chen#include "TimerId.h"
162745a763SShuo Chen
172745a763SShuo Chen#include <boost/scoped_ptr.hpp>
182745a763SShuo Chen#include <vector>
192745a763SShuo Chen
202745a763SShuo Chennamespace muduo
212745a763SShuo Chen{
222745a763SShuo Chen
232745a763SShuo Chenclass Channel;
242745a763SShuo Chenclass Poller;
252745a763SShuo Chenclass TimerQueue;
262745a763SShuo Chen
272745a763SShuo Chenclass EventLoop : boost::noncopyable
282745a763SShuo Chen{
292745a763SShuo Chen public:
302745a763SShuo Chen  typedef boost::function<void()> Functor;
312745a763SShuo Chen
322745a763SShuo Chen  EventLoop();
332745a763SShuo Chen
342745a763SShuo Chen  // force out-line dtor, for scoped_ptr members.
352745a763SShuo Chen  ~EventLoop();
362745a763SShuo Chen
372745a763SShuo Chen  ///
382745a763SShuo Chen  /// Loops forever.
392745a763SShuo Chen  ///
402745a763SShuo Chen  /// Must be called in the same thread as creation of the object.
412745a763SShuo Chen  ///
422745a763SShuo Chen  void loop();
432745a763SShuo Chen
442745a763SShuo Chen  void quit();
452745a763SShuo Chen
462745a763SShuo Chen  ///
472745a763SShuo Chen  /// Time when poll returns, usually means data arrivial.
482745a763SShuo Chen  ///
492745a763SShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
502745a763SShuo Chen
512745a763SShuo Chen  /// Runs callback immediately in the loop thread.
522745a763SShuo Chen  /// It wakes up the loop, and run the cb.
532745a763SShuo Chen  /// If in the same loop thread, cb is run within the function.
542745a763SShuo Chen  /// Safe to call from other threads.
552745a763SShuo Chen  void runInLoop(const Functor& cb);
562745a763SShuo Chen  /// Queues callback in the loop thread.
572745a763SShuo Chen  /// Runs after finish pooling.
582745a763SShuo Chen  /// Safe to call from other threads.
592745a763SShuo Chen  void queueInLoop(const Functor& cb);
602745a763SShuo Chen
612745a763SShuo Chen  // timers
622745a763SShuo Chen
632745a763SShuo Chen  ///
642745a763SShuo Chen  /// Runs callback at 'time'.
652745a763SShuo Chen  /// Safe to call from other threads.
662745a763SShuo Chen  ///
672745a763SShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
682745a763SShuo Chen  ///
692745a763SShuo Chen  /// Runs callback after @c delay seconds.
702745a763SShuo Chen  /// Safe to call from other threads.
712745a763SShuo Chen  ///
722745a763SShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
732745a763SShuo Chen  ///
742745a763SShuo Chen  /// Runs callback every @c interval seconds.
752745a763SShuo Chen  /// Safe to call from other threads.
762745a763SShuo Chen  ///
772745a763SShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
782745a763SShuo Chen
792745a763SShuo Chen  // void cancel(TimerId timerId);
802745a763SShuo Chen
812745a763SShuo Chen  // internal use only
822745a763SShuo Chen  void wakeup();
832745a763SShuo Chen  void updateChannel(Channel* channel);
842745a763SShuo Chen  // void removeChannel(Channel* channel);
852745a763SShuo Chen
862745a763SShuo Chen  void assertInLoopThread()
872745a763SShuo Chen  {
882745a763SShuo Chen    if (!isInLoopThread())
892745a763SShuo Chen    {
902745a763SShuo Chen      abortNotInLoopThread();
912745a763SShuo Chen    }
922745a763SShuo Chen  }
932745a763SShuo Chen
942745a763SShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
952745a763SShuo Chen
962745a763SShuo Chen private:
972745a763SShuo Chen
982745a763SShuo Chen  void abortNotInLoopThread();
992745a763SShuo Chen  void handleRead();  // waked up
1002745a763SShuo Chen  void doPendingFunctors();
1012745a763SShuo Chen
1022745a763SShuo Chen  typedef std::vector<Channel*> ChannelList;
1032745a763SShuo Chen
1042745a763SShuo Chen  bool looping_; /* atomic */
1052745a763SShuo Chen  bool quit_; /* atomic */
1062745a763SShuo Chen  bool callingPendingFunctors_; /* atomic */
1072745a763SShuo Chen  const pid_t threadId_;
1082745a763SShuo Chen  Timestamp pollReturnTime_;
1092745a763SShuo Chen  boost::scoped_ptr<Poller> poller_;
1102745a763SShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
1112745a763SShuo Chen  int wakeupFd_;
1122745a763SShuo Chen  // unlike in TimerQueue, which is an internal class,
1132745a763SShuo Chen  // we don't expose Channel to client.
1142745a763SShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
1152745a763SShuo Chen  ChannelList activeChannels_;
1162745a763SShuo Chen  MutexLock mutex_;
117fd65b0afSShuo Chen  std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_
1182745a763SShuo Chen};
1192745a763SShuo Chen
1202745a763SShuo Chen}
1212745a763SShuo Chen
1222745a763SShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123