summaryrefslogtreecommitdiff
path: root/vxi11_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'vxi11_server.c')
-rw-r--r--vxi11_server.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/vxi11_server.c b/vxi11_server.c
index 57ec50b..8811514 100644
--- a/vxi11_server.c
+++ b/vxi11_server.c
@@ -516,13 +516,31 @@ destroy_link_1_svc(Device_Link *argp, struct svc_req *rqstp) {
Device_Error *
create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) {
static Device_Error result;
+
+ in_port_t port = htons(argp->hostPort);
+ uint32_t addr = htonl(argp->hostAddr);
+
#ifdef DEBUG
printf("create_intr_chan_1_svc()\n");
char clientaddressstring[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &argp->hostAddr, clientaddressstring, sizeof(clientaddressstring));
- printf("Client %s is asking for an interrupt connection on port %u\n", clientaddressstring,
- (unsigned int) argp->hostPort);
+ inet_ntop(AF_INET, &addr, clientaddressstring, sizeof(clientaddressstring));
+ printf("Client %s is asking for an interrupt connection on port %u\n", clientaddressstring, (unsigned int) port);
+#endif
+
+ // if a client had an interrupt channel and died without closing it
+ // we need to clean it up to avoid a deadlock
+ static struct rpc_err err;
+ if (intclient != NULL) {
+ clnt_geterr(intclient, &err);
+ if (err.re_errno != 0) {
+#ifdef DEBUG
+ printf("killing stale client\n");
#endif
+ clnt_destroy(intclient);
+ intclient = NULL;
+ }
+ }
+
if (argp->progFamily != DEVICE_TCP || argp->progNum != DEVICE_INTR || argp->progVers != DEVICE_INTR_VERSION)
result.error = ERR_OPERATIONNOTSUPPORTED;
else if (intclient != NULL) {
@@ -531,8 +549,8 @@ create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) {
else {
struct sockaddr_in clientaddr;
clientaddr.sin_family = AF_INET;
- clientaddr.sin_port = htons(argp->hostPort);
- clientaddr.sin_addr.s_addr = argp->hostAddr;
+ clientaddr.sin_port = port;
+ clientaddr.sin_addr.s_addr = addr;
int sock = RPC_ANYSOCK;
CLIENT* clnt = clnttcp_create(&clientaddr, DEVICE_INTR, DEVICE_INTR_VERSION, &sock, 0, 0);
if (clnt == NULL) {
@@ -544,6 +562,9 @@ create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) {
else {
intclient = clnt;
result.error = 0;
+#ifdef DEBUG
+ printf("Client created\n");
+#endif
}
}
return &result;