├── CMakeLists.txt ├── README.md └── libuv-test.c /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #Standard stuff 2 | cmake_minimum_required(VERSION 2.6) 3 | project(libuv_test) 4 | 5 | #Check threads 6 | set(CMAKE_THREAD_PREFER_PTHREAD 1) 7 | include(FindThreads) 8 | 9 | if(NOT CMAKE_USE_PTHREADS_INIT) 10 | message(FATAL_ERROR "Could not find pthreads") 11 | endif(NOT CMAKE_USE_PTHREADS_INIT) 12 | 13 | #Static way of locating library 14 | find_library(LIBRT_LIBRARY rt) 15 | 16 | if(NOT LIBRT_LIBRARY) 17 | message(FATAL_ERROR "Librt could not be found") 18 | endif(NOT LIBRT_LIBRARY) 19 | 20 | #Add the libuv-dir. Compile this using another CMake-file? 21 | find_library(LIBUV uv lib/libuv) 22 | 23 | include_directories(lib/libuv/include) 24 | add_executable(libuv_test libuv-test.c) 25 | target_link_libraries(libuv_test ${CMAKE_THREAD_LIBS_INIT}) 26 | target_link_libraries(libuv_test ${LIBUV}) 27 | target_link_libraries(libuv_test ${LIBRT_LIBRARY}) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libuv-multiple-loops 2 | ==================== 3 | 4 | An example showing how to use multiple event loops in libuv. The loops run in 5 | two different threads, and the example also shows how threads can communicate. 6 | 7 | Also included is a CMakeLists.txt file, in case you want to use CMake. Remember 8 | to adjust paths to libuv. 9 | -------------------------------------------------------------------------------- /libuv-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* Libuv multiple loops + thread communication example. Written by Kristian 7 | * Evensen */ 8 | 9 | //rpath is needed because it is an argument to the linker (not compiler) about 10 | //where to look 11 | //gcc -Iinclude -g libuv-test.c -o libuv_test -L "./" -l uv -Xlinker -rpath -Xlinker "./" -lrt 12 | 13 | void timer_callback(uv_timer_t *handle, int status){ 14 | uv_async_t *other_thread_notifier = (uv_async_t *) handle->data; 15 | 16 | fprintf(stderr, "Timer expired, notifying other thread\n"); 17 | 18 | //Notify the other thread 19 | uv_async_send(other_thread_notifier); 20 | } 21 | 22 | void *child_thread(void *data){ 23 | uv_loop_t *thread_loop = (uv_loop_t *) data; 24 | fprintf(stderr, "Consumer thread will start event loop\n"); 25 | 26 | //Start this loop 27 | uv_run(thread_loop); 28 | pthread_exit(NULL); 29 | } 30 | 31 | void consumer_notify(uv_async_t *handle, int status){ 32 | fprintf(stderr, "Hello from the other thread\n", handle->loop->backend_fd); 33 | } 34 | 35 | int main(int argc, char *argv[]){ 36 | pthread_t thread; 37 | uv_async_t async; 38 | 39 | /* Create and set up the consumer thread */ 40 | uv_loop_t *thread_loop = uv_loop_new(); 41 | uv_async_init(thread_loop, &async, consumer_notify); 42 | pthread_create(&thread, NULL, child_thread, thread_loop); 43 | 44 | /* Main thread will run default loop */ 45 | uv_loop_t *main_loop = uv_default_loop(); 46 | uv_timer_t timer_req; 47 | uv_timer_init(main_loop, &timer_req); 48 | 49 | /* Timer callback needs async so it knows where to send messages */ 50 | timer_req.data = &async; 51 | uv_timer_start(&timer_req, timer_callback, 0, 2000); 52 | 53 | fprintf(stderr, "Starting main loop\n"); 54 | uv_run(main_loop); 55 | 56 | return 0; 57 | } 58 | --------------------------------------------------------------------------------