Libevent Analysis Notes (1) - Installation and Usage
Introduction to Libevent
The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.
The libevent API provides such a mechanism:
Execute a specified callback function when a specific event occurs in a specified file descriptor, or when a timeout is reached.
Additionally, libevent callback functionality also supports triggering by signals or regular timeouts.
Note that its license is a BSD-style license, which can be used in commercial products without having to open source.
1. Compilation and Installation
In Ubuntu, you can install directly using apt:
~$ sudo apt-get install libevent
Or use:
|
|
2. Library Usage
You can understand the basic usage of libevent from these simple examples. When compiling, you need to add the “-levent” parameter.
2.1. I/O Events (corresponding to EV_READ, EV_WRITE)
Below is a simplified server program snippet that uses libevent to return system time.
1
void get_time(int fd,short event,struct event *arg) ///Get system time and write it back/
2

{
3
……
4
localtime_r(&now,&t);
5
asctime_r(&t,buf);
6
write( fd,buf,strlen(buf) );
7
……
8
}
9
void con_accept(int fd,short event,void *arg) ///Callback function provided to the event, accepts a connection/
10

{
11
struct sockaddr_in s_in;
12
socklen_t len = sizeof(s_in);
13
int ns = accept(fd,(struct sockaddr *) &s_in,&len);
14
struct event *ev = malloc(sizeof(struct event));
15
event_set(ev,ns,EV_WRITE,(void )get_time,ev);
16
event_add(ev,NULL);
17
}
18
19
int main()
20

{
21
int sockfd = socket(PF_INET,SOCK_STREAM,0);
22
struct sockaddr_in s_in;
23
……
24
bind(sockfd,(struct sockaddr) &s_in,sizeof(s_in));
25
listen(sockfd,5);
26
event_init(); //libevent initialization
27
28
struct event ev;
29
event_set(&ev,sockfd,EV_READ|EV_PERSIST,con_accept,&ev);
30
//Set event properties to readable, persistent, callback function is con_accept()
31
event_add(&ev,NULL);//Add event, no timeout set
32
event_dispatch();//Enter libevent main loop
33
return 0;
34
}
35
2.2. Signal Handling Events (corresponding to EV_SIGNAL)
1
static void signal_cb(int fd, short event, void *arg)
2

{
3
struct event *signal = arg;
4
printf("%s: got signal %d\n", func, EVENT_SIGNAL(signal));
5
if (called >= 2)
6
event_del(signal); //If called more than twice, delete this signal
7
called++;
8
}
9
10
int main (int argc, char **argv)
11

{
12
struct event signal_int;
13
event_init();//libevent initialization
14
event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb, &signal_int);
15
//Set event properties to signal-triggered, persistent, callback function is signal_cb()
16
event_add(&signal_int, NULL); //Add event
17
event_dispatch();//Enter libevent main loop
18
return 0;
19
}
20
2.3. Regular Timeout Handling (corresponding to EV_TIMEOUT)
1
static void timeout_cb(int fd, short event, void *arg)
2

{
3
struct timeval tv;
4
struct event *timeout = arg;
5
int newtime = time(NULL);
6
printf("%s: called at %d: %d\n", func, newtime,
7
newtime - lasttime);
8
lasttime = newtime;
9
evutil_timerclear(&tv);
10
tv.tv_sec = 2;
11
event_add(timeout, &tv);
12
}
13
14
int main (int argc, char **argv)
15

{
16
struct event timeout;
17
struct timeval tv;
18
event_init();//libevent initialization
19
evtimer_set(&timeout, timeout_cb, &timeout);
20
//Actually this function corresponds to event_set(timeout, -1, 0, timeout_cb,&timeout)
21
evutil_timerclear(&tv); //If there’s a time clearing function, it directly corresponds to timerclear(), otherwise set tv_sec and tv_usec to 0
22
23
tv.tv_sec = 2;
24
event_add(&timeout, &tv);
25
lasttime = time(NULL);
26
event_dispatch();
27
return 0;
28
}
29
Original link: http://www.cppblog.com/xguru/archive/2010/06/24/118597.html