summaryrefslogtreecommitdiff
path: root/vxi11_server.c
diff options
context:
space:
mode:
authordaniel <danieruru@gmail.com>2013-01-26 13:10:08 +0900
committerdaniel <danieruru@gmail.com>2013-01-26 13:10:08 +0900
commit35b28230e17a68db48f3b5fc91d2eec0c80e048c (patch)
tree3682265dbce6a376a9f65835d718515f448a4972 /vxi11_server.c
parent67801485ab5a9e4509d2bb2cdd9454ee4ed1ab11 (diff)
Add a "hack" to report back to the vxi11 service code when a link dies.
It's a hack because linux/glibc's RPC implementation doesn't seem to have the ability to set a recv error callback. The hack is to add an extra event to the events poll'd.. that event tells us if the socket died.
Diffstat (limited to 'vxi11_server.c')
-rw-r--r--vxi11_server.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/vxi11_server.c b/vxi11_server.c
index ae8317f..4185542 100644
--- a/vxi11_server.c
+++ b/vxi11_server.c
@@ -47,6 +47,7 @@ static gchar* inthandler = NULL;
#define LINKLONGSINCEDEADTIMEOUT ((10 * 60) * 1000000) // ten minutes
typedef struct {
int lid;
+ int sock;
GTimeVal lastactivity;
} ActiveLink;
@@ -66,6 +67,29 @@ static bool isValidLink(int linkid) {
return links[linkid] != NULL;
}
+static void freelink(ActiveLink* link) {
+ links[link->lid] = NULL;
+ globals.Remote.vxi_connections--;
+#ifdef DEBUG
+ printf("link %d destroyed, %d active links\n", link->lid, globals.Remote.vxi_connections);
+#endif
+ g_free(link);
+}
+
+void vxi11_deadsocketcallback(int socket) {
+ int linkid;
+ for (linkid = 0; linkid < SIZEOFARRAY(links); linkid++) {
+ if (links[linkid] != NULL) {
+ if (links[linkid]->sock == socket) {
+#ifdef DEBUG
+ printf("Freeing link %d, socket died\n", linkid);
+#endif
+ freelink(links[linkid]);
+ }
+ }
+ }
+}
+
// test if a link has expired, this is to avoid dead locks
static bool linkexpired(ActiveLink* link) {
GTimeVal cutoff;
@@ -75,9 +99,7 @@ static bool linkexpired(ActiveLink* link) {
#ifdef DEBUG
printf("Link %d is apparently dead, removing\n", link->lid);
#endif
- links[link->lid] = NULL;
- g_free(link);
- globals.Remote.vxi_connections--;
+ freelink(link);
return true;
}
else
@@ -171,10 +193,11 @@ create_link_1_svc(Create_LinkParms *argp, struct svc_req *rqstp) {
}
g_assert(linkid != SIZEOFARRAY(links));
link->lid = linkid;
+ link->sock = rqstp->rq_xprt->xp_sock;
touchlink(linkid);
globals.Remote.vxi_connections++;
#ifdef DEBUG
- printf("created link %d, %d active links\n", linkid, globals.Remote.vxi_connections);
+ printf("created link %d(socket %d), %d active links\n", linkid, link->sock, globals.Remote.vxi_connections);
#endif
struct sockaddr_in sin;
@@ -184,6 +207,7 @@ create_link_1_svc(Create_LinkParms *argp, struct svc_req *rqstp) {
result.abortPort = ntohs(sin.sin_port);
result.maxRecvSize = MAXRECV;
result.lid = linkid;
+
}
}
return &result;
@@ -468,13 +492,8 @@ destroy_link_1_svc(Device_Link *argp, struct svc_req *rqstp) {
unlock();
}
- globals.Remote.vxi_connections--;
-#ifdef DEBUG
- printf("link %d destroyed, %d active links\n", lid, globals.Remote.vxi_connections);
-#endif
+ freelink(links[lid]);
result.error = 0;
- g_free(links[lid]);
- links[lid] = NULL;
}
return &result;