Skip to content

Commit

Permalink
demo: set up input eventfd #390
Browse files Browse the repository at this point in the history
When we process input in the demo, write a packet to an
eventfd we set up in input_dispatcher(). This way,
demo components can poll() on that. #390
  • Loading branch information
dankamongmen committed Mar 1, 2020
1 parent e6bbcd2 commit e679816
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/demo/demo.h
Expand Up @@ -71,6 +71,10 @@ demo_getc_nblock(ncinput* ni){
return demo_getc(&ts, ni);
}

// Get a fd which can be poll()ed to check for outstanding input. Do not close
// this file descriptor.
int demo_input_fd(void);

// 'ni' may be NULL if the caller is uninterested in event details. Blocks
// until an event is processed or a signal is received.
static inline char32_t
Expand Down
29 changes: 23 additions & 6 deletions src/demo/input.c
@@ -1,12 +1,16 @@
#include <pthread.h>
#include <sys/eventfd.h>
#include "demo.h"

typedef struct nciqueue {
ncinput ni;
struct nciqueue *next;
} nciqueue;

static bool spawned;
// an eventfd or pipe on which we write upon receipt of input, so that demos
// can multiplex against other fds.
static int input_eventfd = -1;

static pthread_t tid;
static nciqueue* queue;
static nciqueue** enqueue = &queue;
Expand Down Expand Up @@ -61,6 +65,8 @@ pass_along(const ncinput* ni){
*enqueue = nq;
enqueue = &nq->next;
pthread_mutex_unlock(&lock);
const unsigned char eventcount[1] = "\x01";
write(input_eventfd, eventcount, sizeof(eventcount));
pthread_cond_signal(&cond);
return 0;
}
Expand Down Expand Up @@ -113,23 +119,34 @@ ultramegaok_demo(void* vnc){
return NULL;
}

int demo_input_fd(void){
return input_eventfd;
}

// listens for events, handling mouse events directly and making other ones
// available to demos
// available to demos. returns -1 if already spawned or resource failures.
int input_dispatcher(struct notcurses* nc){
spawned = true;
if(input_eventfd >= 0){
return -1;
}
if((input_eventfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0){
return -1;
}
if(pthread_create(&tid, NULL, ultramegaok_demo, nc)){
spawned = false;
close(input_eventfd);
input_eventfd = -1;
return -1;
}
return 0;
}

int stop_input(void){
int ret = 0;
if(spawned){
if(input_eventfd >= 0){
ret |= pthread_cancel(tid);
ret |= pthread_join(tid, NULL);
spawned = false;
ret |= close(input_eventfd);
input_eventfd = -1;
}
return ret;
}

0 comments on commit e679816

Please sign in to comment.