Last active
November 27, 2023 12:35
-
-
Save DamonHao/df87e727a0299c07fce3 to your computer and use it in GitHub Desktop.
libev example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* test_libv.c | |
* | |
* Created on: May 30, 2014 | |
* Author: damonhao | |
*/ | |
// a single header file is required | |
#include <ev.h> | |
#include <stdio.h> // for puts | |
// every watcher type has its own typedef'd struct | |
// with the name ev_TYPE | |
ev_io stdin_watcher; | |
ev_timer timeout_watcher; | |
// all watcher callbacks have a similar signature | |
// this callback is called when data is readable on stdin | |
static void | |
stdin_cb (EV_P_ ev_io *w, int revents) | |
{ | |
puts ("stdin ready"); | |
// for one-shot events, one must manually stop the watcher | |
// with its corresponding stop function. | |
ev_io_stop (EV_A_ w); | |
// this causes all nested ev_run's to stop iterating | |
ev_break (EV_A_ EVBREAK_ALL); | |
} | |
// another callback, this time for a time-out | |
static void | |
timeout_cb (EV_P_ ev_timer *w, int revents) | |
{ | |
puts ("timeout"); | |
// this causes the innermost ev_run to stop iterating | |
ev_break (EV_A_ EVBREAK_ONE); | |
} | |
int | |
main (void) | |
{ | |
// use the default event loop unless you have special needs | |
struct ev_loop *loop = EV_DEFAULT; | |
// initialise an io watcher, then start it | |
// this one will watch for stdin to become readable | |
ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); | |
ev_io_start (loop, &stdin_watcher); | |
// initialise a timer watcher, then start it | |
// simple non-repeating 5.5 second timeout | |
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); | |
ev_timer_start (loop, &timeout_watcher); | |
// now wait for events to arrive | |
ev_run (loop, 0); | |
// break was called, so exit | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* test_ev_child.c | |
* | |
* Created on: Jun 2, 2014 | |
* Author: damonhao | |
*/ | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <stdio.h> // for puts | |
#include <ev.h> | |
ev_child cw; | |
static void child_cb(EV_P_ ev_child *w, int revents) | |
{ | |
ev_child_stop(EV_A_ w); | |
printf("process %d exited with status %x\n", w->rpid, w->rstatus); | |
} | |
int main() | |
{ | |
pid_t pid = fork(); | |
if (pid < 0) | |
{ | |
// error | |
puts("fork error"); | |
return 0; | |
} | |
else if (pid == 0) | |
{ | |
// the forked child executes here | |
exit(1); | |
} | |
else | |
{ | |
puts("in parent"); | |
struct ev_loop *loop = EV_DEFAULT; | |
ev_child_init(&cw, child_cb, pid, 0); | |
ev_child_start(loop, &cw); | |
ev_run(loop, 0); | |
} | |
return 0; | |
} | |
/*output: | |
in parent | |
process 4472 exited with status 100 | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* test_ev_once.c | |
* | |
* Created on: Jun 2, 2014 | |
* Author: damonhao | |
*/ | |
/* receive io event or timeout. They may happen at the same time, | |
you probably should give io events precedence.*/ | |
#include <unistd.h> | |
#include <stdio.h> // for puts | |
#include <ev.h> | |
static void stdin_ready(int revents, void *arg) | |
{ | |
if (revents & EV_READ) | |
{ | |
/* stdin might have data for us, joy! */ | |
puts("stdin io event"); | |
} | |
else if (revents & EV_TIMER) | |
{ | |
/* doh, nothing entered */ | |
puts("timeout"); | |
} | |
} | |
int main() | |
{ | |
puts("in main"); | |
struct ev_loop *loop = EV_DEFAULT; | |
ev_once (loop, STDIN_FILENO, EV_READ, 5., stdin_ready, NULL); | |
ev_run(loop, 0); | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* test_libev_withthread.c | |
* | |
* Created on: Jun 4, 2014 | |
* Author: damonhao | |
*/ | |
#include <ev.h> | |
#include <pthread.h> | |
typedef struct | |
{ | |
pthread_mutex_t lock; /* global loop lock */ | |
ev_async async_w; | |
pthread_t tid; | |
pthread_cond_t invoke_cv; | |
} userdata; | |
static void async_cb(EV_P_ ev_async *w, int revents) | |
{ | |
// just used for the side effects | |
} | |
static void l_release(EV_P) | |
{ | |
userdata *u = ev_userdata(EV_A); | |
pthread_mutex_unlock(&u->lock); | |
} | |
static void l_acquire(EV_P) | |
{ | |
userdata *u = ev_userdata(EV_A); | |
pthread_mutex_lock(&u->lock); | |
} | |
void *l_run(void *thr_arg) | |
{ | |
struct ev_loop *loop = (struct ev_loop *) thr_arg; | |
l_acquire(EV_A); | |
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); | |
ev_run(EV_A_ 0); | |
l_release(EV_A); | |
return 0; | |
} | |
static void l_invoke(EV_P) | |
{ | |
userdata *u = ev_userdata(EV_A); | |
while (ev_pending_count(EV_A)) | |
{ | |
wake_up_other_thread_in_some_magic_or_not_so_magic_way(); | |
pthread_cond_wait(&u->invoke_cv, &u->lock); | |
} | |
} | |
void prepare_loop(EV_P) | |
{ | |
// for simplicity, we use a static userdata struct. | |
static userdata u; | |
ev_async_init(&u->async_w, async_cb); | |
ev_async_start(EV_A_&u->async_w); | |
pthread_mutex_init(&u->lock, 0); | |
pthread_cond_init(&u->invoke_cv, 0); | |
// now associate this with the loop | |
ev_set_userdata(EV_A_ u); | |
ev_set_invoke_pending_cb(EV_A_ l_invoke); | |
ev_set_loop_release_cb(EV_A_ l_release, l_acquire); | |
// then create the thread running ev_run | |
pthread_create(&u->tid, 0, l_run, EV_A); | |
} | |
static void real_invoke_pending(EV_P) | |
{ | |
userdata *u = ev_userdata(EV_A); | |
pthread_mutex_lock(&u->lock); | |
ev_invoke_pending(EV_A); | |
pthread_cond_signal(&u->invoke_cv); | |
pthread_mutex_unlock(&u->lock); | |
} | |
static void timeout_cb (EV_P_ ev_timer *w, int revents) | |
{ | |
puts ("timeout"); | |
// this causes the innermost ev_run to stop iterating | |
ev_break (EV_A_ EVBREAK_ONE); | |
} | |
int main() | |
{ | |
struct ev_loop *loop = EV_DEFAULT; | |
ev_timer timeout_watcher; | |
userdata *u = ev_userdata (EV_A); | |
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); | |
pthread_mutex_lock (&u->lock); | |
ev_timer_start (EV_A_ &timeout_watcher); | |
ev_async_send (EV_A_ &u->async_w); | |
pthread_mutex_unlock (&u->lock); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* test_watcher_with_customerdata.c | |
* | |
* Created on: Jun 3, 2014 | |
* Author: damonhao | |
*/ | |
// a single header file is required | |
#include <ev.h> | |
#include <unistd.h> | |
#include <stdio.h> // for puts | |
#include <string.h> | |
#define BUFFERSIZE 50 | |
struct my_io | |
{ | |
ev_io io_watcher_; | |
int data_; | |
}; | |
void my_io_cb(struct ev_loop *loop, ev_io *w, int revents) | |
{ | |
struct my_io * custom_watcher = (struct my_io *) w; | |
char buf[BUFFERSIZE]; | |
if (gets(buf) != NULL) //FIXME: note the size of buf, read is unsafe now; | |
{ | |
if (strcmp("end", buf) != 0) | |
{ | |
printf("read data times: %d\n", custom_watcher->data_); | |
custom_watcher->data_++; | |
puts(buf); | |
} | |
else | |
{ | |
ev_io_stop(loop, w); | |
ev_break(loop, EVBREAK_ALL); | |
} | |
} | |
else | |
{ | |
puts("read error"); | |
} | |
} | |
int main() | |
{ | |
puts("in main"); | |
struct ev_loop *loop = EV_DEFAULT; | |
struct my_io custom_watcher; | |
custom_watcher.data_ = 1; | |
ev_io_init(&custom_watcher.io_watcher_, my_io_cb, STDIN_FILENO, EV_READ); | |
ev_io_start(loop, &custom_watcher.io_watcher_); | |
ev_run(loop, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment