#include #include #include #include "libvxi11client.h" #define DEBUG #ifdef DEBUG #include #endif static GAsyncQueue* interruptqueue; typedef struct { gchar* handle; } Event; static Event* lastevent = NULL; // perl is responsible for freeing the handle static void freeevent(Event* event) { g_free(event); } static void freelast() { if (lastevent != NULL ) { freeevent(lastevent); lastevent = NULL; } } static void interruptcallback(gchar* handle) { Event* event = g_malloc(sizeof(Event)); event->handle = handle; g_async_queue_push(interruptqueue, event); } VXI11Context* glue_open(char* address, char* device) { VXI11Context* context = malloc(sizeof(VXI11Context)); if (context == NULL ) return NULL ; int err = vxi11_open(context, address, device); return context; } int glue_start_interrupt_server() { interruptqueue = g_async_queue_new(); g_async_queue_ref(interruptqueue); return vxi11_start_interrupt_server(interruptcallback); } int glue_stop_interrupt_server() { int ret = vxi11_stop_interrupt_server(); Event* event = NULL; // clear everything that is left over while ((event = (Event*) g_async_queue_try_pop(interruptqueue)) != NULL ) { freeevent(event); } freelast(); g_async_queue_unref(interruptqueue); interruptqueue = NULL; return ret; } char* glue_wait_for_interrupt(int timeout) { if (interruptqueue == NULL ) { #ifdef DEBUG printf("interrupt queue is null!\n"); #endif return NULL ; } // if we have a timeout pop with a time out // otherwise block until an interrupt happens freelast(); if (timeout > 0) { GTimeVal whentotimeout; g_get_current_time(&whentotimeout); g_time_val_add(&whentotimeout, timeout * 1000); lastevent = (Event*) g_async_queue_timed_pop(interruptqueue, &whentotimeout); } else if (timeout == 0) { lastevent = (Event*) g_async_queue_try_pop(interruptqueue); } else if (timeout == -1) { lastevent = (Event*) g_async_queue_pop(interruptqueue); } if (lastevent != NULL ) { return lastevent->handle; } else return NULL ; }