Please note that this is a Libev rather than a libevent article.
This article is the second, mainly about Libev in the watcher of some basic operations.
This article address: https://segmentfault.com/a/1190000006200077 Watcher Analysis
Here is a schematic of the code, using the Ev_io:
static void My_cb (struct ev_loop *loop, ev_io *w, int revents)
{
ev_io_stop (w);
Ev_break (Loop, evbreak_all);
}
Some_main ()
{
...
struct Ev_loop *loop = ev_default_loop (0);
Ev_io Stdin_watcher;
Ev_init (&stdin_watcher, MY_CB);
Ev_io_set (&stdin_watcher, Stdin_fileno, ev_read);
Ev_io_start (Loop, &stdin_watcher);
Ev_run (loop, 0);
...
}
Each of the watcher types has an attached watcher structure. (typically struct ev_xxx or ev_xxx)
Each watcher structure needs to be initialized with Ev_init, each watcher has corresponding ev_xxx_set function, Ev_xxx_start function, Ev_xxx_stop function. Ev_start of each watcher prior to Ev_run.
As long as Watcher is active, you can no longer invoke init.
Each callback has three parameters: loop, Watcher, and the mask value of the event. The possible mask values are:
Ev_read
Ev_write
Ev_timer:ev_timer Timeout
Ev_periodic:ev_periodic Timeout
Ev_signal: A thread has received the SIGNAL specified in ev_signal
The PID specified in the Ev_child:ev_child gets a state change
The properties of path specified in Ev_stat:ev_stat modify the
Ev_idle:ev_idle Watcher found nothing to do.
Ev_prepare, Ev_check: All ev_prepare watchers are called before loop starts collecting events, and all Ev_check watchers are called later. The callback can start/stop the corresponding watchers in these two watchers.
Ev_embed:ev_embed Watcher
Ev_cleanup:event loop is about to be destroyed.
Ev_async:asuny Watcher has been asynchronously notified
Ev_custom: Not a signal sent by Libev. See Ev_feed_event
Ev_error: May occur when Libev memory is insufficient, and a general watcher function may be generated when the FD is closed externally
void Ev_init (Ev_type *watcher, callback)
Use this macro to initialize the watcher. You will also need to invoke the corresponding Ev_xxx_set function. See below:
void Ev_type_set (Ev_type *watcher, [args])
Sets the wetaher of the specified type. The INIT function must be called once before, and the set function can be set any time thereafter.
This function cannot be called on an active watcher, but pending can. Like what:
Ev_io W;
Ev_init (&w, MY_CB);
Ev_io_set (&w, Stdin_fileno, Ev_read);
void Ev_type_set (Ev_type *watcher, Callback, [args])
This macro combines init and set to use
void Ev_type_start (Loop, Ev_type *watcher)
Starts (activates) the specified watcher. If Watcher is already active, the call is not valid.
void Ev_type_stop (Loop, Ev_type *watcher)
Stop watcher and empty the pending state. If you want to release a watcher, it is a good idea to explicitly call stop.
BOOL Ev_is_active (Ev_type *watcher)
Returns true if Watcher was executed once to start and was not stop.
BOOL Ev_is_pending (Ev_type *watcher)
Returns True when and only if watcher pending. (eg: there are pending events, but callback is not called)
Callback EV_CB (Ev_type *watcher)
void Ev_set_cb (Ev_type *watcher, callback)
Read/write Callback
void Ev_set_priority (Ev_type *watcher, int priority)
int ev_priority (Ev_type *watcher)
Priority is a value between Ev_maxpri (default 2) and Ev_min_pri (Default-2). Higher values are called first. But in addition to Ev_idle, every watcher will be called.
When Watcher is active or pending, it cannot be modified.
In fact the range of priority greater than 2 to 2 is also no problem.
void Ev_invoke (Loop, ev_type *watcher, int revents);
Invokes the callback using the specified parameters
int ev_clear_pending (loop, Ev_type *watcher);
Clears the pending state of the specified watcher and returns the Revents bit. Returns 0 if Watcher is not pending
void Ev_feed_event (Loop, ev_type *watcher, int revents)
Simulates an event. See Ev_feed_fd_event and Ev_feed_signal_event watcher states
In addition to the active and pending states mentioned earlier, this section describes a more detailed watcher state.
Initialized: Initializes the watcher by calling Ev_type_init, which is the necessary step before registering to loop. You can call Ev_type_init again to operate.
Started/running/active: Calls the state after Ev_type_start and starts waiting for the event. In this state, except for the few cases specifically mentioned, it cannot be accessed, moved, released, and can only maintain pointers to it.
Pending: Watcher enters pending when Watcher is active and an event of interest to watcher arrives. The watcher of this state can access, but cannot access, move, and release.
Stopped: Call Ev_type_stop, at which point the state is the same as initialized. series of articles
Libev Official Document Learning Note (1)--Overview and Ev_loop
Libev Official Document Learning Notes (2)--watcher Basics (This article)
Libev Official Documentation Learning Note (3)--Common Watcher interface
using Libev Simple process for building a TCP response server