Error[8]: Undefined offset: 740, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

文章目录


全流程实现博客链接

从零开始自制实现C++ High-Performance WebServer 全流程记录(基于muduo网络库)


前引

还有两个TimerLogging


(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)
1、timer.h
#ifndef TINY_MUDUO_TIMER_H_
#define TINY_MUDUO_TIMER_H_

#include 

#include "timestamp.h"
#include "noncopyable.h"

namespace tiny_muduo {

class Timer : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  Timer(Timestamp timestamp, BasicFunc&& cb, double interval);

  void Restart(Timestamp now) {
    expiration_ = Timestamp::AddTime(now, interval_);
  }

  void Run() const {
    callback_();
  }

  Timestamp expiration() const { return expiration_; }
  bool repeat() const { return repeat_; }

 private:
  Timestamp expiration_; 
  BasicFunc callback_;
  double interval_; 
  bool repeat_;
};

} // namespace tiny_muduo

#endif

1、timer.cc
#include "timer.h"

#include 

using namespace tiny_muduo;

Timer::Timer(Timestamp expiration, BasicFunc&& cb, double interval = 0.0)
    : expiration_(expiration),
      callback_(std::move(cb)),
      interval_(interval),
      repeat_(interval > 0.0) {
}

2、timerqueue.h
#ifndef TINY_MUDUO_TIMERQUEUE_H_
#define TINY_MUDUO_TIMERQUEUE_H_

#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "timer.h"
#include "timestamp.h"
#include "noncopyable.h"
#include "logging.h"

namespace tiny_muduo {

class EventLoop;
class Channel;

class TimerQueue : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  TimerQueue(EventLoop* loop);
  ~TimerQueue();

  void ReadTimerFd() {
    uint64_t read_byte;
    ssize_t readn = ::read(timerfd_, &read_byte, sizeof(read_byte));
    if (readn != sizeof(read_byte)) {
      LOG_ERROR	 << "TimerQueue::ReadTimerFd read_size < 0";
    }
  }

  void HandleRead() {
    ReadTimerFd();
    Timestamp expiration_time(Timestamp::Now());

    active_timers_.clear();    
    auto end = timers_.lower_bound(TimerPair(Timestamp::Now(), reinterpret_cast<Timer*>(UINTPTR_MAX)));
    active_timers_.insert(active_timers_.end() , timers_.begin(), end);
    timers_.erase(timers_.begin(), end);
    
    for (const auto& timerpair : active_timers_) {
      timerpair.second->Run();
    } 
    ResetTimers();
  }

  void ResetTimers() {
    for (auto& timerpair: active_timers_) {
      if ((timerpair.second)->repeat()) {
        auto timer = timerpair.second;
        timer->Restart(Timestamp::Now());
        Insert(timer);
      } else {
        delete timerpair.second;
      }
    } 

    if (!timers_.empty()) {
      ResetTimer(timers_.begin()->second);
    }
  }

  bool Insert(Timer* timer) {
    bool reset_instantly = false;
    if (timers_.empty() || timer->expiration() < timers_.begin()->first ) {
      reset_instantly = true;
    }

    timers_.emplace(std::move(TimerPair(timer->expiration(), timer)));
    return reset_instantly;
  }

  void AddTimerInLoop(Timer* timer) {
    bool reset_instantly = Insert(timer);
    if (reset_instantly) {
      ResetTimer(timer);
    }
  }

  void ResetTimer(Timer* timer);
  void AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval);

 private:
  typedef std::pair<Timestamp, Timer*> TimerPair;
  typedef std::set<TimerPair> TimersSet; 
  typedef std::vector<TimerPair> ActiveTimers;

  EventLoop* loop_;
  int timerfd_;
  std::unique_ptr<Channel> channel_; 

  TimersSet timers_;
  ActiveTimers active_timers_;
};

} // namesapce tiny_muduo

#endif

2、timerqueue.cc
#include "timerqueue.h"

#include 
#include 

#include 

#include "channel.h"

using namespace tiny_muduo;

TimerQueue::TimerQueue(EventLoop* loop)
    : loop_(loop),
      timerfd_(::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC)),
      channel_(new Channel(loop_, timerfd_)) {
  channel_->SetReadCallback(std::bind(&TimerQueue::HandleRead, this));
  channel_->EnableReading();
}

TimerQueue::~TimerQueue() {
  channel_->DisableAll();
  loop_->Remove(channel_.get());
  close(timerfd_);

  for (const auto& timerpair : timers_) {
    delete timerpair.second;
  } 
}

void TimerQueue::AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval) {
  Timer* timer(new Timer(timestamp, std::move(cb), interval));
  loop_->RunOneFunc(std::bind(&TimerQueue::AddTimerInLoop, this, timer));
}

void TimerQueue::ResetTimer(Timer* timer) {
  struct itimerspec new_;
  struct itimerspec old_;
  memset(&new_, ','sizeof ()new_);memset
  (&,old_',' sizeof( ))old_;int64_t=

  expiration micro_seconds_dif ( timer->).microseconds()-Timestamp :: Now().microseconds();if(
  < 100micro_seconds_dif ) =100 {
    micro_seconds_dif ; }.
  .
 
  new_=it_valuestatic_casttv_sec < (/time_t>)
      micro_seconds_dif ; kMicrosecond2Second..
  new_=it_valuestatic_casttv_nsec < long((>%
      )micro_seconds_dif * kMicrosecond2Second1000 ) ;int=
  :: ret timerfd_settime (,0timerfd_, &, &new_) ;old_assert(
  !=-ret 1 );(void
  );} ret[+++]
[+++]
)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 741, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

文章目录


全流程实现博客链接

从零开始自制实现C++ High-Performance WebServer 全流程记录(基于muduo网络库)


前引

还有两个TimerLogging


(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)
1、timer.h
#ifndef TINY_MUDUO_TIMER_H_
#define TINY_MUDUO_TIMER_H_

#include 

#include "timestamp.h"
#include "noncopyable.h"

namespace tiny_muduo {

class Timer : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  Timer(Timestamp timestamp, BasicFunc&& cb, double interval);

  void Restart(Timestamp now) {
    expiration_ = Timestamp::AddTime(now, interval_);
  }

  void Run() const {
    callback_();
  }

  Timestamp expiration() const { return expiration_; }
  bool repeat() const { return repeat_; }

 private:
  Timestamp expiration_; 
  BasicFunc callback_;
  double interval_; 
  bool repeat_;
};

} // namespace tiny_muduo

#endif

1、timer.cc
#include "timer.h"

#include 

using namespace tiny_muduo;

Timer::Timer(Timestamp expiration, BasicFunc&& cb, double interval = 0.0)
    : expiration_(expiration),
      callback_(std::move(cb)),
      interval_(interval),
      repeat_(interval > 0.0) {
}

2、timerqueue.h
#ifndef TINY_MUDUO_TIMERQUEUE_H_
#define TINY_MUDUO_TIMERQUEUE_H_

#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "timer.h"
#include "timestamp.h"
#include "noncopyable.h"
#include "logging.h"

namespace tiny_muduo {

class EventLoop;
class Channel;

class TimerQueue : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  TimerQueue(EventLoop* loop);
  ~TimerQueue();

  void ReadTimerFd() {
    uint64_t read_byte;
    ssize_t readn = ::read(timerfd_, &read_byte, sizeof(read_byte));
    if (readn != sizeof(read_byte)) {
      LOG_ERROR	 << "TimerQueue::ReadTimerFd read_size < 0";
    }
  }

  void HandleRead() {
    ReadTimerFd();
    Timestamp expiration_time(Timestamp::Now());

    active_timers_.clear();    
    auto end = timers_.lower_bound(TimerPair(Timestamp::Now(), reinterpret_cast<Timer*>(UINTPTR_MAX)));
    active_timers_.insert(active_timers_.end() , timers_.begin(), end);
    timers_.erase(timers_.begin(), end);
    
    for (const auto& timerpair : active_timers_) {
      timerpair.second->Run();
    } 
    ResetTimers();
  }

  void ResetTimers() {
    for (auto& timerpair: active_timers_) {
      if ((timerpair.second)->repeat()) {
        auto timer = timerpair.second;
        timer->Restart(Timestamp::Now());
        Insert(timer);
      } else {
        delete timerpair.second;
      }
    } 

    if (!timers_.empty()) {
      ResetTimer(timers_.begin()->second);
    }
  }

  bool Insert(Timer* timer) {
    bool reset_instantly = false;
    if (timers_.empty() || timer->expiration() < timers_.begin()->first ) {
      reset_instantly = true;
    }

    timers_.emplace(std::move(TimerPair(timer->expiration(), timer)));
    return reset_instantly;
  }

  void AddTimerInLoop(Timer* timer) {
    bool reset_instantly = Insert(timer);
    if (reset_instantly) {
      ResetTimer(timer);
    }
  }

  void ResetTimer(Timer* timer);
  void AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval);

 private:
  typedef std::pair<Timestamp, Timer*> TimerPair;
  typedef std::set<TimerPair> TimersSet; 
  typedef std::vector<TimerPair> ActiveTimers;

  EventLoop* loop_;
  int timerfd_;
  std::unique_ptr<Channel> channel_; 

  TimersSet timers_;
  ActiveTimers active_timers_;
};

} // namesapce tiny_muduo

#endif

2、timerqueue.cc
#include "timerqueue.h"

#include 
#include 

#include 

#include "channel.h"

using namespace tiny_muduo;

TimerQueue::TimerQueue(EventLoop* loop)
    : loop_(loop),
      timerfd_(::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC)),
      channel_(new Channel(loop_, timerfd_)) {
  channel_->SetReadCallback(std::bind(&TimerQueue::HandleRead, this));
  channel_->EnableReading();
}

TimerQueue::~TimerQueue() {
  channel_->DisableAll();
  loop_->Remove(channel_.get());
  close(timerfd_);

  for (const auto& timerpair : timers_) {
    delete timerpair.second;
  } 
}

void TimerQueue::AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval) {
  Timer* timer(new Timer(timestamp, std::move(cb), interval));
  loop_->RunOneFunc(std::bind(&TimerQueue::AddTimerInLoop, this, timer));
}

void TimerQueue::ResetTimer(Timer* timer) {
  struct itimerspec new_;
  struct itimerspec old_;
  memset(&new_, ','sizeof ()new_);memset
  (&,old_',' sizeof( ))old_;int64_t=

  expiration micro_seconds_dif ( timer->).microseconds()-Timestamp :: Now().microseconds();if(
  < 100micro_seconds_dif ) =100 {
    micro_seconds_dif ; }.
  .
 
  new_=it_valuestatic_casttv_sec < (/time_t>)
      micro_seconds_dif ; kMicrosecond2Second..
  new_=it_valuestatic_casttv_nsec < long((>%
      )micro_seconds_dif * kMicrosecond2Second1000 ) ;int=
  :: ret timerfd_settime (,0timerfd_, &, &new_) ;old_assert(
  !=-ret 1 );(void
  );} ret
[+++]
)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
从零开始自制实现WebServer(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)_C_内存溢出

从零开始自制实现WebServer(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)

从零开始自制实现WebServer(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分),第1张

文章目录
    • 全流程实现博客链接
    • 前引
    • (二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)
      • 1、timer.h
      • 1、timer.cc
      • 2、timerqueue.h
      • 2、timerqueue.cc


全流程实现博客链接

从零开始自制实现C++ High-Performance WebServer 全流程记录(基于muduo网络库)


前引

还有两个TimerLogging


(二十)---- C++ High-Performance WebServer源码实现(Timer核心代码部分)
1、timer.h
#ifndef TINY_MUDUO_TIMER_H_
#define TINY_MUDUO_TIMER_H_

#include 

#include "timestamp.h"
#include "noncopyable.h"

namespace tiny_muduo {

class Timer : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  Timer(Timestamp timestamp, BasicFunc&& cb, double interval);

  void Restart(Timestamp now) {
    expiration_ = Timestamp::AddTime(now, interval_);
  }

  void Run() const {
    callback_();
  }

  Timestamp expiration() const { return expiration_; }
  bool repeat() const { return repeat_; }

 private:
  Timestamp expiration_; 
  BasicFunc callback_;
  double interval_; 
  bool repeat_;
};

} // namespace tiny_muduo

#endif

1、timer.cc
#include "timer.h"

#include 

using namespace tiny_muduo;

Timer::Timer(Timestamp expiration, BasicFunc&& cb, double interval = 0.0)
    : expiration_(expiration),
      callback_(std::move(cb)),
      interval_(interval),
      repeat_(interval > 0.0) {
}

2、timerqueue.h
#ifndef TINY_MUDUO_TIMERQUEUE_H_
#define TINY_MUDUO_TIMERQUEUE_H_

#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "timer.h"
#include "timestamp.h"
#include "noncopyable.h"
#include "logging.h"

namespace tiny_muduo {

class EventLoop;
class Channel;

class TimerQueue : public NonCopyAble {
 public:
  typedef std::function<void()> BasicFunc;

  TimerQueue(EventLoop* loop);
  ~TimerQueue();

  void ReadTimerFd() {
    uint64_t read_byte;
    ssize_t readn = ::read(timerfd_, &read_byte, sizeof(read_byte));
    if (readn != sizeof(read_byte)) {
      LOG_ERROR	 << "TimerQueue::ReadTimerFd read_size < 0";
    }
  }

  void HandleRead() {
    ReadTimerFd();
    Timestamp expiration_time(Timestamp::Now());

    active_timers_.clear();    
    auto end = timers_.lower_bound(TimerPair(Timestamp::Now(), reinterpret_cast<Timer*>(UINTPTR_MAX)));
    active_timers_.insert(active_timers_.end() , timers_.begin(), end);
    timers_.erase(timers_.begin(), end);
    
    for (const auto& timerpair : active_timers_) {
      timerpair.second->Run();
    } 
    ResetTimers();
  }

  void ResetTimers() {
    for (auto& timerpair: active_timers_) {
      if ((timerpair.second)->repeat()) {
        auto timer = timerpair.second;
        timer->Restart(Timestamp::Now());
        Insert(timer);
      } else {
        delete timerpair.second;
      }
    } 

    if (!timers_.empty()) {
      ResetTimer(timers_.begin()->second);
    }
  }

  bool Insert(Timer* timer) {
    bool reset_instantly = false;
    if (timers_.empty() || timer->expiration() < timers_.begin()->first ) {
      reset_instantly = true;
    }

    timers_.emplace(std::move(TimerPair(timer->expiration(), timer)));
    return reset_instantly;
  }

  void AddTimerInLoop(Timer* timer) {
    bool reset_instantly = Insert(timer);
    if (reset_instantly) {
      ResetTimer(timer);
    }
  }

  void ResetTimer(Timer* timer);
  void AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval);

 private:
  typedef std::pair<Timestamp, Timer*> TimerPair;
  typedef std::set<TimerPair> TimersSet; 
  typedef std::vector<TimerPair> ActiveTimers;

  EventLoop* loop_;
  int timerfd_;
  std::unique_ptr<Channel> channel_; 

  TimersSet timers_;
  ActiveTimers active_timers_;
};

} // namesapce tiny_muduo

#endif

2、timerqueue.cc
#include "timerqueue.h"

#include 
#include 

#include 

#include "channel.h"

using namespace tiny_muduo;

TimerQueue::TimerQueue(EventLoop* loop)
    : loop_(loop),
      timerfd_(::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC)),
      channel_(new Channel(loop_, timerfd_)) {
  channel_->SetReadCallback(std::bind(&TimerQueue::HandleRead, this));
  channel_->EnableReading();
}

TimerQueue::~TimerQueue() {
  channel_->DisableAll();
  loop_->Remove(channel_.get());
  close(timerfd_);

  for (const auto& timerpair : timers_) {
    delete timerpair.second;
  } 
}

void TimerQueue::AddTimer(Timestamp timestamp, BasicFunc&& cb, double interval) {
  Timer* timer(new Timer(timestamp, std::move(cb), interval));
  loop_->RunOneFunc(std::bind(&TimerQueue::AddTimerInLoop, this, timer));
}

void TimerQueue::ResetTimer(Timer* timer) {
  struct itimerspec new_;
  struct itimerspec old_;
  memset(&new_, ','sizeof ()new_);memset
  (&,old_',' sizeof( ))old_;int64_t=

  expiration micro_seconds_dif ( timer->).microseconds()-Timestamp :: Now().microseconds();if(
  < 100micro_seconds_dif ) =100 {
    micro_seconds_dif ; }.
  .
 
  new_=it_valuestatic_casttv_sec < (/time_t>)
      micro_seconds_dif ; kMicrosecond2Second..
  new_=it_valuestatic_casttv_nsec < long((>%
      )micro_seconds_dif * kMicrosecond2Second1000 ) ;int=
  :: ret timerfd_settime (,0timerfd_, &, &new_) ;old_assert(
  !=-ret 1 );(void
  );} ret

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/728514.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存