Libev is a lightweight, high-performance network library for event loop/event models. Similar to libevent, libev open source code is obscure and hard to understand. It can be described as the ultimate use of macros, the code is concise. Libev provides comprehensive functions, including
- Ev_io
- Ev_timer
- Ev_periodic
- Ev_signal
- Ev_child
- Ev_stat
- Ev_idle
- Ev_prepare and ev_check
- Ev_embed
- Ev_fork
- Ev_cleanup
- Ev_async
This article mainly describes how to use timer and how to encapsulate it in a simple way. This is a common method for developing software. During prototype development, open source can be used to make full use of open source resources, however, whether the official development will use open source or implement a library by yourself is to be evaluated. Therefore, open-source interfaces can be considered for encapsulation. When other libraries are used, the replacement workload is small.
The following is the implementation code:
Call the ev_loop_new ev_loop, ev_timer_init, ev_timer_stop, and ev_timer_start interfaces in libev to encapsulate the timer function.
#ifndef _dims_timer_h_#define _dims_timer_h_#include <pthread.h>#include "dims_base.h"#include "ev.h"typedef void (*dims_timer_cb)(void *arg);typedef struct dims_watcher_tag{structdims_watcher_tag *next;dims_uint32 type; dims_timer_cb timer_cb;void*pvData;ev_timertimer_watcher; }dims_watcher_t;typedef struct dims_timer_tag{dims_uint32 bInited;dims_timer_cbinit_cb;void*pvData;dims_watcher_t*watcher_list;pthread_tthread_id;pthread_mutex_tlock;struct ev_loop *loop;}dims_timer_t;extern dims_uint32 dims_timer_create(dims_timer_t *timer, dims_timer_cb init_cb, void *pvInitData);extern void dims_timer_init(dims_timer_t *timer, dims_timer_cb timer_cb,dims_uint32 type,void *pvData,double after,double repeat);extern void dims_timer_start(dims_timer_t *timer, dims_uint32 type);extern void dims_timer_stop(dims_timer_t *timer, dims_uint32 type);#endif /* _dims_timer_h_ */
/** Encapsulate the libev timer operation */# include <eV. h> # include <stdlib. h> # include "dims_timer.h" static void timer_watcher_cb (ev_p _ ev_timer * w, int revents) {dims_watcher_t * watcher = (dims_watcher_t *) W-> data; if (! Watcher) return; If (watcher-> timer_cb) watcher-> timer_cb (watcher);} static void * timer_loop_entry (void * Arg) {dims_timer_t * timer = (timer *) ARG; static ev_timer W; If (! Timer) return 0; If (timer-> binited) return 0; timer-> loop = ev_loop_new (0); timer-> binited = 1; if (timer-> init_cb) timer-> init_cb (ARG); ev_timer_init (& W, timer_watcher_cb, 1, 0); ev_timer_start (timer-> loop, & W); ev_loop (timer-> loop, 0); Return 0;} dims_uint32 dims_timer_create (dims_timer_t * timer, dims_timer_cb init_cb, void * pvdata) {If (! Timer) return dims_error; timer-> binited = 0; timer-> init_cb = init_cb; timer-> pvdata = pvdata; timer-> watcher_list = dims_null; pthread_mutex_init (& timer-> lock, 0); If (0! = Pthread_create (& (timer-> thread_id), null, timer_loop_entry, (void *) timer) {return dims_error;} while (! Timer-> binited) sleep (0); Return dims_ OK;} static void dims_watcher_del (dims_timer_t * timer, dims_uint32 type) {dims_watcher_t * w = timer-> watcher_list; dims_watcher_t * prev_w = 0; while (w) {If (W-> type = type) break; prev_w = W; W = W-> next;} If (W) {If (prev_w) prev_w-> next = W-> next; else timer-> watcher_list = 0; free (w) ;}} static dims_watcher_t * dims_watcher_find (dims_timer_t * timer, dims_uint32 type) {dims_w Atcher_t * w = timer-> watcher_list; while (w) {If (W-> type = type) break; W = W-> next;} return W ;} static void dims_watcher_ins (optional * timer, dims_watcher_t * w) {w-> next = timer-> watcher_list; timer-> watcher_list = W;} void dims_timer_init (optional * timer, dims_timer_cb timer_cb, dims_uint32type, void * pvdata, double after, double repeat) {dims_watcher_t * watcher; If (! Timer) return; pthread_mutex_lock (& timer-> lock); watcher = dims_watcher_find (timer, type); If (watcher) {ev_timer_stop (timer-> loop, & watcher-> timer_watcher);} else {watcher = (dims_watcher_t *) malloc (sizeof (percentage); dims_watcher_ins (timer, Watcher);} watcher-> timer_cb = timer_cb; watcher-> type = type; watcher-> timer_watcher.data = (void *) watcher; watcher-> pvdata = pvdata; ev_timer_init (& watcher-> timer _ Watcher, timer_watcher_cb, after, repeat); unlock (& timer-> lock); return;} void dims_timer_start (timer * timer, dims_uint32 type) {dims_watcher_t * w; If (! Timer) return; pthread_mutex_lock (& timer-> lock); W = dims_watcher_find (timer, type); If (w) {ev_timer_start (timer-> loop, & W-> timer_watcher);} pthread_mutex_unlock (& timer-> lock); return;} void dims_timer_stop (dims_timer_t * timer, dims_uint32type) {If (! Timer) return; dims_watcher_t * watcher; pthread_mutex_lock (& timer-> lock); watcher = dims_watcher_find (timer, type); If (watcher) {ev_timer_stop (timer-> loop, & watcher-> timer_watcher); dims_watcher_del (timer, type);} pthread_mutex_unlock (& timer-> lock); return ;}
In the code, the Type field is mainly used to differentiate the timer type. For example, if a program requires multiple timers, you can uniquely differentiate the type here. The same type is considered to be the same timer. You can also perform different processing based on type when calling callback.
The timer can be reset, started, and stopped.
The dims_timer_init () function initializes a timer.
Test:
# Include <stdio. h> # include "dims_timer.h" # include <unistd. h> dims_timer_t my_timer; int CB1, CB2; void my_init_cb (void * Arg) {dims_timer_t * TMR = (optional *) ARG; printf ("timer init % s \ n ", (char *) TMR-> pvdata);} void my_cb (void * Arg) {dims_watcher_t * w = ARG; printf ("% s CB1 = % d \ n ", (char *) W-> pvdata, CB1); CB1 ++;} void my_cb_1 (void * Arg) {dims_watcher_t * w = ARG; printf ("% s CB2 = % d, type = % d \ n", (char *) W-> PV Data, CB2, W-> type); CB2 ++; If (CB2> 20) dims_timer_stop (& my_timer, 1);} int main (INT argc, char ** argv) {dims_timer_create (& my_timer, my_init_cb, "OK !!! "); Dims_timer_init (& my_timer, my_cb, 0," Call-1 ", 1, 0.1); // timed out in 1 s seconds, and timed out in the next interval of S. Dims_timer_init (& my_timer, my_cb_1, 1, "Call-2", 1.0, 0.5); dims_timer_start (& my_timer, 0); dims_timer_start (& my_timer, 1 ); sleep (2); dims_timer_stop (& my_timer, 0); sleep (8); dims_timer_stop (& my_timer, 1); sleep (20); Return 0 ;}
Libev document Introduction: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_timer_code_relative_and_opti
Libev Official Website: http://software.schmorp.de/pkg/libev.html