summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libvxi11client/client.c10
-rw-r--r--libvxi11client/libvxi11client.c95
-rw-r--r--libvxi11client/libvxi11client.h5
3 files changed, 60 insertions, 50 deletions
diff --git a/libvxi11client/client.c b/libvxi11client/client.c
index b851347..f712f29 100644
--- a/libvxi11client/client.c
+++ b/libvxi11client/client.c
@@ -27,7 +27,7 @@ static char* geterrorstring(int errorcode) {
}
}
-static void interruptcallback(void) {
+static void interruptcallback(char* handle) {
printf("Interrupt fired\n");
}
@@ -40,6 +40,8 @@ int main(int argc, char *argv[]) {
exit(1);
}
+ vxi11_start_interrupt_server(interruptcallback);
+
Context ctx;
int err = 0;
@@ -144,7 +146,7 @@ int main(int argc, char *argv[]) {
printf("Created interrupt channel\n");
// enable interrupts
- if ((err = vxi11_enable_srq(&ctx, true, "handle", interruptcallback)) > 0)
+ if ((err = vxi11_enable_srq(&ctx, true, "handle")) > 0)
printf("Enabled interrupts\n");
else
printf("Error enabling interrupts; %s\n", geterrorstring(err));
@@ -152,7 +154,7 @@ int main(int argc, char *argv[]) {
sleep(10);
// disable interrupts
- if ((err = vxi11_enable_srq(&ctx, false, NULL, NULL)) > 0)
+ if ((err = vxi11_enable_srq(&ctx, false, NULL)) > 0)
printf("Disabled interrupts\n");
else
printf("Error disabling interrupts; %s\n", geterrorstring(err));
@@ -176,6 +178,8 @@ int main(int argc, char *argv[]) {
// close
if ((err = vxi11_close(&ctx) > 0))
printf("Closed\n");
+
+ vxi11_stop_interrupt_server();
}
else {
printf("Error opening device; %s\n", geterrorstring(err));
diff --git a/libvxi11client/libvxi11client.c b/libvxi11client/libvxi11client.c
index 614f6a6..8936545 100644
--- a/libvxi11client/libvxi11client.c
+++ b/libvxi11client/libvxi11client.c
@@ -26,17 +26,9 @@
#define VXI11_DEFAULT_TIMEOUT 1000
static GThread* interruptthread;
-static bool interruptchannelopen = false;
-static void (*interruptcallback)(void) = NULL;
-
-static void killinterruptthreadandwait() {
-#ifdef DEBUG
- printf("Waiting for interrupt thread to die\n");
-#endif
- interruptchannelopen = false;
- g_thread_join(interruptthread);
- interruptthread = NULL;
-}
+static void (*interruptcallback)(char*) = NULL;
+static bool interruptserverstarted = false;
+static unsigned int interruptserverport = -1;
void *
device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) {
@@ -45,7 +37,7 @@ device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) {
#endif
if (interruptcallback != NULL) {
- interruptcallback();
+ interruptcallback(argp->handle.handle_val);
}
static char * result;
@@ -146,6 +138,9 @@ int vxi11_open(Context* context, char* address, char* device) {
// failed!
return 0;
+ context->interruptchannelopen = false;
+ context->interruptsenabled = false;
+
return 1;
}
else if (linkresp == NULL)
@@ -379,7 +374,7 @@ static gpointer interruptthreadfunc(gpointer data) {
struct pollfd *my_pollfd = NULL;
int last_max_pollfd = 0;
- while (interruptchannelopen) {
+ while (interruptserverstarted) {
int max_pollfd = svc_max_pollfd;
if (max_pollfd == 0 && svc_pollfd == NULL)
break;
@@ -421,44 +416,57 @@ static gpointer interruptthreadfunc(gpointer data) {
return NULL;
}
-/**
- * create an interrupt channel from the connected device
- */
-int vxi11_create_intr_chan(Context* context) {
- if (interruptchannelopen)
- return 0;
- else if (context->clnt == NULL)
- return 0;
- else if (interruptthread != NULL)
- return 0;
-
- interruptchannelopen = true;
- unsigned int port = -1;
+int vxi11_start_interrupt_server(void (*callback)(char* handle)) {
+ interruptcallback = callback;
+ interruptserverstarted = true;
g_thread_init(NULL);
- interruptthread = g_thread_create(interruptthreadfunc, &port, true, NULL);
+ interruptthread = g_thread_create(interruptthreadfunc, &interruptserverport, true, NULL);
if (interruptthread == NULL)
return 0;
- while (port == -1) { // spin
+ while (interruptserverport == -1) { // spin
usleep(200);
};
+ return 1;
+}
+
+int vxi11_stop_interrupt_server() {
+#ifdef DEBUG
+ printf("Waiting for interrupt thread to die\n");
+#endif
+ interruptserverstarted = false;
+ g_thread_join(interruptthread);
+ interruptthread = NULL;
+ return 1;
+}
+
+/**
+ * create an interrupt channel from the connected device
+ */
+int vxi11_create_intr_chan(Context* context) {
+ if (context->clnt == NULL || context->interruptchannelopen)
+ return 0;
+ else if (interruptthread == NULL) {
+#ifdef DEBUG
+ printf("interrupt thread isn't running\n");
+#endif
+ return 0;
+ }
struct sockaddr_in myaddress;
get_myaddress(&myaddress);
- Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = port, .progNum = DEVICE_INTR,
- .progVers = DEVICE_INTR_VERSION, .progFamily = DEVICE_TCP };
+ Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = interruptserverport, .progNum =
+ DEVICE_INTR, .progVers = DEVICE_INTR_VERSION, .progFamily = DEVICE_TCP };
Device_Error* error = create_intr_chan_1(&remotefunc, context->clnt);
- if (error != NULL && error->error == 0)
+ if (error != NULL && error->error == 0) {
+ context->interruptchannelopen = true;
return 1;
- else if (error == NULL) {
- killinterruptthreadandwait();
- return 0;
}
- else {
- killinterruptthreadandwait();
+ else if (error == NULL)
+ return 0;
+ else
return -(error->error);
- }
}
/**
@@ -466,16 +474,14 @@ int vxi11_create_intr_chan(Context* context) {
*/
int vxi11_destroy_intr_chan(Context* context) {
- if (!interruptchannelopen)
- return 0;
- else if (context->clnt == NULL)
+ if (context->clnt == NULL || !(context->interruptchannelopen))
return 0;
else if (interruptthread == NULL)
return 0;
Device_Error* error = destroy_intr_chan_1(NULL, context->clnt);
if (error != NULL && error->error == 0) {
- killinterruptthreadandwait();
+ context->interruptchannelopen = false;
return 1;
}
else if (error == NULL)
@@ -488,10 +494,8 @@ int vxi11_destroy_intr_chan(Context* context) {
* enable interrupts
*/
-int vxi11_enable_srq(Context* context, bool enable, char* handle, void (*callback)(void)) {
- if (!interruptchannelopen)
- return 0;
- else if (context->clnt == NULL)
+int vxi11_enable_srq(Context* context, bool enable, char* handle) {
+ if (context->clnt == NULL || !(context->interruptchannelopen))
return 0;
else if (interruptthread == NULL)
return 0;
@@ -502,7 +506,6 @@ int vxi11_enable_srq(Context* context, bool enable, char* handle, void (*callbac
params.handle.handle_val = handle;
params.handle.handle_len = strlen(handle) + 1;
}
- interruptcallback = callback;
}
else {
params.handle.handle_val = NULL;
diff --git a/libvxi11client/libvxi11client.h b/libvxi11client/libvxi11client.h
index 0546ac4..27da46c 100644
--- a/libvxi11client/libvxi11client.h
+++ b/libvxi11client/libvxi11client.h
@@ -20,6 +20,7 @@ typedef struct {
CLIENT* clnt;
CLIENT* abortclnt;
Device_Link devicelink;
+ bool interruptchannelopen;
bool interruptsenabled;
} Context;
@@ -36,6 +37,8 @@ int vxi11_remote(Context* context, bool waitforlock);
int vxi11_readstatusbyte(Context* context, bool waitforlock);
int vxi11_create_intr_chan(Context* context);
int vxi11_destroy_intr_chan(Context* context);
-int vxi11_enable_srq(Context* context, bool enable, char* handle, void (*callback)(void));
+int vxi11_enable_srq(Context* context, bool enable, char* handle);
+int vxi11_start_interrupt_server(void (*callback)(char* handle));
+int vxi11_stop_interrupt_server();
int vxi11_docmd(Context* context, unsigned long cmd, bool waitforlock);
int vxi11_close(Context* context);