119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati#include <gtest/gtest.h> 219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati#include <pthread.h> 3fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati#include <sys/eventfd.h> 419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati#include <sys/time.h> 519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati#include <unistd.h> 619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 7384f8a948e9837475c4f504a626205334522df2aZach Johnson#include "AllocationTestHarness.h" 8384f8a948e9837475c4f504a626205334522df2aZach Johnson 919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatiextern "C" { 1019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati#include "reactor.h" 1119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 1219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 13384f8a948e9837475c4f504a626205334522df2aZach Johnsonclass ReactorTest : public AllocationTestHarness {}; 14384f8a948e9837475c4f504a626205334522df2aZach Johnson 1519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatistatic pthread_t thread; 1619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatistatic volatile bool thread_running; 1719084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 1819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatistatic void *reactor_thread(void *ptr) { 1919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = (reactor_t *)ptr; 2019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 2119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati thread_running = true; 2219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_start(reactor); 2319084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati thread_running = false; 2419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 2519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati return NULL; 2619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 2719084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 2819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatistatic void spawn_reactor_thread(reactor_t *reactor) { 2919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati int ret = pthread_create(&thread, NULL, reactor_thread, reactor); 3019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati EXPECT_EQ(ret, 0); 3119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 3219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 3319084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavatistatic void join_reactor_thread() { 3419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati pthread_join(thread, NULL); 3519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 3619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 37384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_new) { 3819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = reactor_new(); 3919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati EXPECT_TRUE(reactor != NULL); 4019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(reactor); 4119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 4219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 43384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_free_null) { 4419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(NULL); 4519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 4619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 47384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_stop_start) { 4819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = reactor_new(); 4919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_stop(reactor); 5019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_start(reactor); 5119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(reactor); 5219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 5319084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 54384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_repeated_stop_start) { 5519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = reactor_new(); 5619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati for (int i = 0; i < 10; ++i) { 5719084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_stop(reactor); 5819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_start(reactor); 5919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati } 6019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(reactor); 6119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 6219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 63384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_start_wait_stop) { 6419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = reactor_new(); 6519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 6619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati spawn_reactor_thread(reactor); 6719084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati usleep(50 * 1000); 6819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati EXPECT_TRUE(thread_running); 6919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 7019084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_stop(reactor); 7119084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati join_reactor_thread(); 7219084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati EXPECT_FALSE(thread_running); 7319084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 7419084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(reactor); 7519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 7619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 77fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavatitypedef struct { 78fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_t *reactor; 79fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_object_t *object; 80fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati} unregister_arg_t; 81fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 82fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavatistatic void unregister_cb(void *context) { 83fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati unregister_arg_t *arg = (unregister_arg_t *)context; 84fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_unregister(arg->object); 85fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_stop(arg->reactor); 86fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati} 87fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 88384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_unregister_from_callback) { 89fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_t *reactor = reactor_new(); 90fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 91fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati int fd = eventfd(0, 0); 92fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati unregister_arg_t arg; 93fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati arg.reactor = reactor; 94fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati arg.object = reactor_register(reactor, fd, &arg, unregister_cb, NULL); 95fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati spawn_reactor_thread(reactor); 96fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati eventfd_write(fd, 1); 97fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 98fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati join_reactor_thread(); 99fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 100fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati close(fd); 101fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_free(reactor); 102fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati} 103fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 104384f8a948e9837475c4f504a626205334522df2aZach JohnsonTEST_F(ReactorTest, reactor_unregister_from_separate_thread) { 10519084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_t *reactor = reactor_new(); 10619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 107fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati int fd = eventfd(0, 0); 108fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 109fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_object_t *object = reactor_register(reactor, fd, NULL, NULL, NULL); 110fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati spawn_reactor_thread(reactor); 111fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati usleep(50 * 1000); 112fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_unregister(object); 113fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 114fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati reactor_stop(reactor); 115fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati join_reactor_thread(); 11619084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati 117fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati close(fd); 11819084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati reactor_free(reactor); 11919084c6242d8ddb366a52eba5084c974280cce0fSharvil Nanavati} 120