104e5c324SShuo Chen// excerpts from http://code.google.com/p/muduo/
204e5c324SShuo Chen//
304e5c324SShuo Chen// Use of this source code is governed by a BSD-style license
404e5c324SShuo Chen// that can be found in the License file.
504e5c324SShuo Chen//
604e5c324SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
704e5c324SShuo Chen
804e5c324SShuo Chen#ifndef MUDUO_NET_CONNECTOR_H
904e5c324SShuo Chen#define MUDUO_NET_CONNECTOR_H
1004e5c324SShuo Chen
1104e5c324SShuo Chen#include "InetAddress.h"
12f4e8e3d3SShuo Chen#include "TimerId.h"
1304e5c324SShuo Chen
1404e5c324SShuo Chen#include <boost/enable_shared_from_this.hpp>
1504e5c324SShuo Chen#include <boost/function.hpp>
1604e5c324SShuo Chen#include <boost/noncopyable.hpp>
1704e5c324SShuo Chen#include <boost/scoped_ptr.hpp>
1804e5c324SShuo Chen
1904e5c324SShuo Chennamespace muduo
2004e5c324SShuo Chen{
2104e5c324SShuo Chen
2204e5c324SShuo Chenclass Channel;
2304e5c324SShuo Chenclass EventLoop;
2404e5c324SShuo Chen
25f4e8e3d3SShuo Chenclass Connector : boost::noncopyable
2604e5c324SShuo Chen{
2704e5c324SShuo Chen public:
2804e5c324SShuo Chen  typedef boost::function<void (int sockfd)> NewConnectionCallback;
2904e5c324SShuo Chen
3004e5c324SShuo Chen  Connector(EventLoop* loop, const InetAddress& serverAddr);
3104e5c324SShuo Chen  ~Connector();
3204e5c324SShuo Chen
3304e5c324SShuo Chen  void setNewConnectionCallback(const NewConnectionCallback& cb)
3404e5c324SShuo Chen  { newConnectionCallback_ = cb; }
3504e5c324SShuo Chen
3604e5c324SShuo Chen  void start();  // can be called in any thread
3704e5c324SShuo Chen  void restart();  // must be called in loop thread
3804e5c324SShuo Chen  void stop();  // can be called in any thread
3904e5c324SShuo Chen
4004e5c324SShuo Chen  const InetAddress& serverAddress() const { return serverAddr_; }
4104e5c324SShuo Chen
4204e5c324SShuo Chen private:
4304e5c324SShuo Chen  enum States { kDisconnected, kConnecting, kConnected };
4404e5c324SShuo Chen  static const int kMaxRetryDelayMs = 30*1000;
4504e5c324SShuo Chen  static const int kInitRetryDelayMs = 500;
4604e5c324SShuo Chen
4704e5c324SShuo Chen  void setState(States s) { state_ = s; }
4804e5c324SShuo Chen  void startInLoop();
4904e5c324SShuo Chen  void connect();
5004e5c324SShuo Chen  void connecting(int sockfd);
5104e5c324SShuo Chen  void handleWrite();
5204e5c324SShuo Chen  void handleError();
5304e5c324SShuo Chen  void retry(int sockfd);
5404e5c324SShuo Chen  int removeAndResetChannel();
5504e5c324SShuo Chen  void resetChannel();
5604e5c324SShuo Chen
5704e5c324SShuo Chen  EventLoop* loop_;
5804e5c324SShuo Chen  InetAddress serverAddr_;
5904e5c324SShuo Chen  bool connect_; // atomic
6004e5c324SShuo Chen  States state_;  // FIXME: use atomic variable
6104e5c324SShuo Chen  boost::scoped_ptr<Channel> channel_;
6204e5c324SShuo Chen  NewConnectionCallback newConnectionCallback_;
6304e5c324SShuo Chen  int retryDelayMs_;
64f4e8e3d3SShuo Chen  TimerId timerId_;
6504e5c324SShuo Chen};
6604e5c324SShuo Chentypedef boost::shared_ptr<Connector> ConnectorPtr;
6704e5c324SShuo Chen
6804e5c324SShuo Chen}
6904e5c324SShuo Chen
7004e5c324SShuo Chen#endif  // MUDUO_NET_CONNECTOR_H
71