#include #include #include #include #include #include "ucore/iomux.h" #include "ucore/iomux_waker.h" pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static int counter = 0; static int please_exit = 0; void wake_cb(struct IOMuxWaker *wk) { int local_counter; int exit_now; int rc; rc = pthread_mutex_lock(&lock); assert(rc == 0); local_counter = counter; exit_now = please_exit; printf("counter is %d\n", local_counter); rc = pthread_mutex_unlock(&lock); assert(rc == 0); if (exit_now) { rc = uc_iomux_waker_destroy(wk); assert(rc == 0); } } void *waker(void *arg) { struct IOMuxSignaller *s = arg; int i; int rc; rc = pthread_mutex_lock(&lock); assert(rc == 0); for (i = 0; i < 3; i++) { counter++; //with the signal in here, //the wake_cb might be woken up //more than once after the loop is done //reading the same counter value more than once. rc = uc_iomux_waker_signal(s); assert(rc == 0); } rc = pthread_mutex_unlock(&lock); assert(rc == 0); for (i = 0; i < 10; i++) { rc = pthread_mutex_lock(&lock); assert(rc == 0); counter++; rc = pthread_mutex_unlock(&lock); assert(rc == 0); rc = uc_iomux_waker_signal(s); assert(rc == 0); } rc = pthread_mutex_lock(&lock); assert(rc == 0); please_exit = 1; //must wake it inside the mutex, else we risk a race //when the waker is destroyed rc = uc_iomux_waker_signal(s); assert(rc == 0); rc = pthread_mutex_unlock(&lock); return NULL; } int main(int argc, char *argv[]) { struct IOMux *mux = iomux_create(IOMUX_TYPE_SELECT); struct IOMuxWaker wk; pthread_t tid; uc_iomux_waker_init(mux, &wk, wake_cb); pthread_create(&tid,NULL,waker, &wk.signaller); iomux_run(mux); printf("reader mux returned\n"); pthread_join(tid, NULL); iomux_delete(mux); return 0; }