在服务端中,我们需要一个定时器去检测客户端的连接情况或者系统的信号。
链表定时器头文件
//
// Created by wenfan on 3/11/21.
//
#ifndef TEST_CLION_UTIL_TIMER_H
#define TEST_CLION_UTIL_TIMER_H
#define BUFFSIZE 64
#include <netinet/in.h>
#include <time.h>
class util_timer;
struct client_data{
sockaddr_in address;
int sockfd;
char buf[BUFFSIZE];
util_timer* timer;
};
class util_timer {
public:
time_t expire; //the expire time of task, absolute time
void (*cb_func)(client_data*);
util_timer* prev; // previous timer node
util_timer* next; // next timer node
client_data* user_data;
public:
util_timer(): prev(NULL),next(NULL){}
};
/**
* ordered link list, have head and tail node
*/
class sort_timer_lst{
public:
sort_timer_lst();
~sort_timer_lst();
void add_timer(util_timer*);
void adjust_timer(util_timer*);
void del_timer(util_timer*);
void tick();
private:
void add_timer(util_timer*,util_timer*);
private:
util_timer* head;
util_timer* tail;
};
#endif //TEST_CLION_UTIL_TIMER_H
链表定时器实现
//
// Created by wenfan on 3/11/21.
//
#include <cstdio>
#include "util_timer.h"
sort_timer_lst::sort_timer_lst() {
head = NULL;
tail = NULL;
}
sort_timer_lst::~sort_timer_lst() {
util_timer* tmp = head;
while(tmp){
head = tmp->next;
delete tmp;
tmp = head;
}
}
void sort_timer_lst::add_timer(util_timer* timer){
if(!timer)
return;
if(!head){
head = tail = timer;
return;
}
if(timer->expire < head->expire){
timer->next = head;
head->prev = timer;
head = timer;
return;
}
add_timer(timer, head);
}
/**
* insert timer after lst_head
* @param timer
* @param lst_head
*/
void sort_timer_lst::add_timer(util_timer * timer, util_timer * lst_head) {
util_timer* prev = lst_head;
util_timer* tmp = prev->next;
while(tmp){
if(timer->expire < tmp->expire){
prev->next = timer;
timer->next = tmp;
tmp->prev = timer;
timer->prev = prev;
break;
}
prev = tmp;
tmp = tmp->next;
}
/**
* node after lst_head is NULL
*/
if(!tmp){
prev->next = timer;
timer->prev = prev;
timer->next = NULL;
tail = timer;
}
}
/**
*
* @param timer
*/
void sort_timer_lst::adjust_timer(util_timer* timer){
if(!timer)
return;
util_timer* tmp = timer->next;
if(!tmp || timer->expire < tmp->expire)
return;
/**
* adjusted target node is head
*/
if(timer == head){
head = head->next;
head->prev = NULL;
timer->next = NULL;
add_timer(timer,head);
}else{
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
add_timer(timer, timer->next);
}
}
void sort_timer_lst::del_timer(util_timer * timer) {
if(!timer)
return;
if(timer == head && timer == tail){
delete timer;
head = tail = NULL;
return ;
}
if(head == timer){
head = head->next;
head->prev = NULL;
delete timer;
return;
}
if(tail == timer){
tail = tail->prev;
tail->next = NULL;
delete timer;
return ;
}
// middle pos of link list
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
delete timer;
}
void sort_timer_lst::tick() {
if(!head)
return;
printf("timer tick\n");
time_t cur = time(NULL); // get current time of sys
util_timer* tmp = head;
// handle node from the head alternatly
while(tmp){
if(cur < tmp->expire){
break;
}
tmp->cb_func(tmp->user_data);
head = tmp->next;
if(head){
head->prev = NULL;
}
delete tmp;
tmp = head;
}
}
代码很简单。就是普通的链表的操作。