diff options
Diffstat (limited to 'vxi11_server.c')
-rw-r--r-- | vxi11_server.c | 31 |
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; |