From 326914f92aeb690e5e70320a131a170f91da181f Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 12 Aug 2020 01:07:45 +0100 Subject: [PATCH] Add example file that's been there forever --- example.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 example.c diff --git a/example.c b/example.c new file mode 100644 index 0000000..ed1df19 --- /dev/null +++ b/example.c @@ -0,0 +1,88 @@ +//This program is demo for using pthreads with libev. +//Try using Timeout values as large as 1.0 and as small as 0.000001 +//and notice the difference in the output + +//(c) 2009 debuguo +//(c) 2013 enthusiasticgeek for stack overflow +//Free to distribute and improve the code. Leave credits intact + +#include +#include // for puts +#include +#include +#include + +pthread_mutex_t lock; +double timeout = 0.00001; +ev_timer timeout_watcher; +int timeout_count = 0; + +ev_async async_watcher; +int async_count = 0; + +struct ev_loop* loop2; + +void* loop2thread(void* args) +{ + printf("Inside loop 2"); // Here one could initiate another timeout watcher + ev_loop(loop2, 0); // similar to the main loop - call it say timeout_cb1 + return NULL; +} + +static void async_cb (EV_P_ ev_async *w, int revents) +{ + //puts ("async ready"); + pthread_mutex_lock(&lock); //Don't forget locking + ++async_count; + printf("async = %d, timeout = %d \n", async_count, timeout_count); + pthread_mutex_unlock(&lock); //Don't forget unlocking +} + +static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function +{ + //puts ("timeout"); + if (ev_async_pending(&async_watcher)==false) { //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to) + ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop. + } + + pthread_mutex_lock(&lock); //Don't forget locking + ++timeout_count; + pthread_mutex_unlock(&lock); //Don't forget unlocking + w->repeat = timeout; + ev_timer_again(loop, &timeout_watcher); //Start the timer again. +} + +int main (int argc, char** argv) +{ + if (argc < 2) { + puts("Timeout value missing.\n./demo "); + return -1; + } + timeout = atof(argv[1]); + + struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0); + + //Initialize pthread + pthread_mutex_init(&lock, NULL); + pthread_t thread; + + // This loop sits in the pthread + loop2 = ev_loop_new(0); + + //This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.) + //This takes into account thread safety + ev_async_init(&async_watcher, async_cb); + ev_async_start(loop2, &async_watcher); + pthread_create(&thread, NULL, loop2thread, NULL); + + ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function + ev_timer_start (loop, &timeout_watcher); + + // now wait for events to arrive + ev_loop(loop, 0); + //Wait on threads for execution + pthread_join(thread, NULL); + + pthread_mutex_destroy(&lock); + return 0; +}