summaryrefslogtreecommitdiff
path: root/vxi11_svc.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_svc.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_svc.c')
-rw-r--r--vxi11_svc.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/vxi11_svc.c b/vxi11_svc.c
index edc4212..e5c4b38 100644
--- a/vxi11_svc.c
+++ b/vxi11_svc.c
@@ -1,12 +1,18 @@
+#define _GNU_SOURCE
+
#include "vxi11.h"
+#include "vxi11_server.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
+#include <poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#define VXI11_DEFAULT_TIMEOUT 1000
+
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
@@ -223,6 +229,51 @@ void vxi_main() {
exit(1);
}
- svc_run();
- fprintf(stderr, "%s", "svc_run returned");
+ int i, j;
+ struct pollfd *my_pollfd = NULL;
+ int last_max_pollfd = 0;
+
+ while (1) {
+ int max_pollfd = svc_max_pollfd;
+ if (max_pollfd == 0 && svc_pollfd == NULL)
+ break;
+
+ if (last_max_pollfd != max_pollfd) {
+ struct pollfd *new_pollfd = realloc(my_pollfd, sizeof(struct pollfd) * max_pollfd);
+
+ if (new_pollfd == NULL) {
+ break;
+ }
+
+ my_pollfd = new_pollfd;
+ last_max_pollfd = max_pollfd;
+ }
+
+ for (i = 0; i < max_pollfd; ++i) {
+ my_pollfd[i].fd = svc_pollfd[i].fd;
+ my_pollfd[i].events = svc_pollfd[i].events | POLLRDHUP; // add the "socket is dead" event
+ my_pollfd[i].revents = 0;
+ }
+
+ j = poll(my_pollfd, max_pollfd, VXI11_DEFAULT_TIMEOUT);
+
+ for (i = 0; i < max_pollfd; i++) {
+ if (my_pollfd[i].revents & POLLRDHUP)
+ vxi11_deadsocketcallback(my_pollfd[i].fd);
+ }
+
+ switch (j) {
+ case -1:
+ break;
+ case 0:
+ continue;
+ default:
+ svc_getreq_poll(my_pollfd, i);
+ continue;
+ }
+ break;
+ }
+
+ //svc_run();
+ //fprintf(stderr, "%s", "svc_run returned");
}