Last active
December 16, 2020 03:29
-
-
Save Kronuz/1d2bb1802383ace72e94 to your computer and use it in GitHub Desktop.
This file contains 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
// The following code can be extended to multiple threads | |
//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 <ev.h> | |
#include <stdio.h> // for puts | |
#include <stdlib.h> | |
#include <pthread.h> | |
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 <timeout>"); | |
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; | |
} |
I think we may need to... not sure why it isn’t there. This was a long time ago, so it may have slipped.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
do we need to call ev_loop_detroy to loop2? because ev_loop_new return a raw pointer