12a18e699SShuo Chen// excerpts from http://code.google.com/p/muduo/
22a18e699SShuo Chen//
32a18e699SShuo Chen// Use of this source code is governed by a BSD-style license
42a18e699SShuo Chen// that can be found in the License file.
52a18e699SShuo Chen//
62a18e699SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
72a18e699SShuo Chen
82a18e699SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
92a18e699SShuo Chen#define MUDUO_NET_EVENTLOOP_H
102a18e699SShuo Chen
112a18e699SShuo Chen#include "datetime/Timestamp.h"
122a18e699SShuo Chen#include "thread/Mutex.h"
132a18e699SShuo Chen#include "thread/Thread.h"
142a18e699SShuo Chen#include "Callbacks.h"
152a18e699SShuo Chen#include "TimerId.h"
162a18e699SShuo Chen
172a18e699SShuo Chen#include <boost/scoped_ptr.hpp>
182a18e699SShuo Chen#include <vector>
192a18e699SShuo Chen
202a18e699SShuo Chennamespace muduo
212a18e699SShuo Chen{
222a18e699SShuo Chen
232a18e699SShuo Chenclass Channel;
242a18e699SShuo Chenclass Poller;
252a18e699SShuo Chenclass TimerQueue;
262a18e699SShuo Chen
272a18e699SShuo Chenclass EventLoop : boost::noncopyable
282a18e699SShuo Chen{
292a18e699SShuo Chen public:
302a18e699SShuo Chen  typedef boost::function<void()> Functor;
312a18e699SShuo Chen
322a18e699SShuo Chen  EventLoop();
332a18e699SShuo Chen
342a18e699SShuo Chen  // force out-line dtor, for scoped_ptr members.
352a18e699SShuo Chen  ~EventLoop();
362a18e699SShuo Chen
372a18e699SShuo Chen  ///
382a18e699SShuo Chen  /// Loops forever.
392a18e699SShuo Chen  ///
402a18e699SShuo Chen  /// Must be called in the same thread as creation of the object.
412a18e699SShuo Chen  ///
422a18e699SShuo Chen  void loop();
432a18e699SShuo Chen
442a18e699SShuo Chen  void quit();
452a18e699SShuo Chen
462a18e699SShuo Chen  ///
472a18e699SShuo Chen  /// Time when poll returns, usually means data arrivial.
482a18e699SShuo Chen  ///
492a18e699SShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
502a18e699SShuo Chen
512a18e699SShuo Chen  /// Runs callback immediately in the loop thread.
522a18e699SShuo Chen  /// It wakes up the loop, and run the cb.
532a18e699SShuo Chen  /// If in the same loop thread, cb is run within the function.
542a18e699SShuo Chen  /// Safe to call from other threads.
552a18e699SShuo Chen  void runInLoop(const Functor& cb);
562a18e699SShuo Chen  /// Queues callback in the loop thread.
572a18e699SShuo Chen  /// Runs after finish pooling.
582a18e699SShuo Chen  /// Safe to call from other threads.
592a18e699SShuo Chen  void queueInLoop(const Functor& cb);
602a18e699SShuo Chen
612a18e699SShuo Chen  // timers
622a18e699SShuo Chen
632a18e699SShuo Chen  ///
642a18e699SShuo Chen  /// Runs callback at 'time'.
652a18e699SShuo Chen  /// Safe to call from other threads.
662a18e699SShuo Chen  ///
672a18e699SShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
682a18e699SShuo Chen  ///
692a18e699SShuo Chen  /// Runs callback after @c delay seconds.
702a18e699SShuo Chen  /// Safe to call from other threads.
712a18e699SShuo Chen  ///
722a18e699SShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
732a18e699SShuo Chen  ///
742a18e699SShuo Chen  /// Runs callback every @c interval seconds.
752a18e699SShuo Chen  /// Safe to call from other threads.
762a18e699SShuo Chen  ///
772a18e699SShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
782a18e699SShuo Chen
792a18e699SShuo Chen  // void cancel(TimerId timerId);
802a18e699SShuo Chen
812a18e699SShuo Chen  // internal use only
822a18e699SShuo Chen  void wakeup();
832a18e699SShuo Chen  void updateChannel(Channel* channel);
842a18e699SShuo Chen  void removeChannel(Channel* channel);
852a18e699SShuo Chen
862a18e699SShuo Chen  void assertInLoopThread()
872a18e699SShuo Chen  {
882a18e699SShuo Chen    if (!isInLoopThread())
892a18e699SShuo Chen    {
902a18e699SShuo Chen      abortNotInLoopThread();
912a18e699SShuo Chen    }
922a18e699SShuo Chen  }
932a18e699SShuo Chen
942a18e699SShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
952a18e699SShuo Chen
962a18e699SShuo Chen private:
972a18e699SShuo Chen
982a18e699SShuo Chen  void abortNotInLoopThread();
992a18e699SShuo Chen  void handleRead();  // waked up
1002a18e699SShuo Chen  void doPendingFunctors();
1012a18e699SShuo Chen
1022a18e699SShuo Chen  typedef std::vector<Channel*> ChannelList;
1032a18e699SShuo Chen
1042a18e699SShuo Chen  bool looping_; /* atomic */
1052a18e699SShuo Chen  bool quit_; /* atomic */
1062a18e699SShuo Chen  bool callingPendingFunctors_; /* atomic */
1072a18e699SShuo Chen  const pid_t threadId_;
1082a18e699SShuo Chen  Timestamp pollReturnTime_;
1092a18e699SShuo Chen  boost::scoped_ptr<Poller> poller_;
1102a18e699SShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
1112a18e699SShuo Chen  int wakeupFd_;
1122a18e699SShuo Chen  // unlike in TimerQueue, which is an internal class,
1132a18e699SShuo Chen  // we don't expose Channel to client.
1142a18e699SShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
1152a18e699SShuo Chen  ChannelList activeChannels_;
1162a18e699SShuo Chen  MutexLock mutex_;
117fd65b0afSShuo Chen  std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_
1182a18e699SShuo Chen};
1192a18e699SShuo Chen
1202a18e699SShuo Chen}
1212a18e699SShuo Chen
1222a18e699SShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123