FBSD: give osi_NetReceive time to shutdown, reprise
[openafs.git] / src / rx / FBSD / rx_knet.c
index c24176f..187ee4c 100644 (file)
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
-#ifdef AFS_FBSD40_ENV
 #include <sys/malloc.h>
 #include "rx/rx_kcommon.h"
 
 #ifdef RXK_LISTENER_ENV
 int
-osi_NetReceive(osi_socket asocket, struct sockaddr_storage *saddr, int *slen,
+osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr,
               struct iovec *dvec, int nvecs, int *alength)
 {
     struct uio u;
@@ -43,11 +40,7 @@ osi_NetReceive(osi_socket asocket, struct sockaddr_storage *saddr, int *slen,
     u.uio_resid = *alength;
     u.uio_segflg = UIO_SYSSPACE;
     u.uio_rw = UIO_READ;
-#ifdef AFS_FBSD50_ENV
     u.uio_td = NULL;
-#else
-    u.uio_procp = NULL;
-#endif
 
     if (haveGlock)
        AFS_GUNLOCK();
@@ -68,10 +61,8 @@ osi_NetReceive(osi_socket asocket, struct sockaddr_storage *saddr, int *slen,
     *alength -= u.uio_resid;
     if (sa) {
        if (sa->sa_family == AF_INET) {
-           if (saddr) {
-               memcpy(saddr, sa, sa->sa_len);
-               *slen = sa->sa_len;
-           }
+           if (addr)
+               *addr = *(struct sockaddr_in *)sa;
        } else
            printf("Unknown socket family %d in NetReceive\n", sa->sa_family);
        FREE(sa, M_SONAME);
@@ -79,6 +70,8 @@ osi_NetReceive(osi_socket asocket, struct sockaddr_storage *saddr, int *slen,
     return code;
 }
 
+#define so_is_disconn(so) ((so)->so_state & SS_ISDISCONNECTED)
+
 extern int rxk_ListenerPid;
 void
 osi_StopListener(void)
@@ -90,22 +83,46 @@ osi_StopListener(void)
      * soclose() is currently protected by Giant,
      * but pfind and psignal are MPSAFE.
      */
-    AFS_GUNLOCK();
-    soclose(rx_socket);
+    int haveGlock = ISAFS_GLOCK();
+    if (haveGlock)
+       AFS_GUNLOCK();
+    soshutdown(rx_socket, SHUT_RDWR);
     p = pfind(rxk_ListenerPid);
+    afs_warn("osi_StopListener: rxk_ListenerPid %lx\n", p);
     if (p)
        psignal(p, SIGUSR1);
-#ifdef AFS_FBSD50_ENV
     PROC_UNLOCK(p);
+#ifdef AFS_FBSD70_ENV
+    {
+      /* Avoid destroying socket until osi_NetReceive has
+       * had a chance to clean up */
+      int tries;
+      struct mtx s_mtx;
+
+      MUTEX_INIT(&s_mtx, "rx_shutdown_mutex", MUTEX_DEFAULT, 0);
+      MUTEX_ENTER(&s_mtx);
+      tries = 3;
+      while ((tries > 0) && (!so_is_disconn(rx_socket))) {
+          afs_warn("osi_StopListener: waiting (%d) ", tries);
+       msleep(&osi_StopListener, &s_mtx, PSOCK | PCATCH,
+              "rx_shutdown_timedwait", 1 * hz);
+       --tries;
+      }
+      if (so_is_disconn(rx_socket))
+          soclose(rx_socket);
+      MUTEX_EXIT(&s_mtx);
+      MUTEX_DESTROY(&s_mtx);
+    }
 #endif
-    AFS_GLOCK();
+    if (haveGlock)
+       AFS_GLOCK();
 }
 
 int
-osi_NetSend(osi_socket asocket, struct sockaddr_storage *saddr, int salen,
-           struct iovec *dvec, int nvecs, afs_int32 alength, int istack)
+osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
+           int nvecs, afs_int32 alength, int istack)
 {
-    register afs_int32 code;
+    afs_int32 code;
     int i;
     struct iovec iov[RX_MAXIOVECS];
     struct uio u;
@@ -124,28 +141,18 @@ osi_NetSend(osi_socket asocket, struct sockaddr_storage *saddr, int salen,
     u.uio_resid = alength;
     u.uio_segflg = UIO_SYSSPACE;
     u.uio_rw = UIO_WRITE;
-#ifdef AFS_FBSD50_ENV
     u.uio_td = NULL;
-#else
-    u.uio_procp = NULL;
-#endif
 
-    saddr->ss_len = saddr->ss_family == AF_INET6 ?
-               sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+    addr->sin_len = sizeof(struct sockaddr_in);
 
     if (haveGlock)
        AFS_GUNLOCK();
 #if KNET_DEBUG
     printf("+");
 #endif
-#ifdef AFS_FBSD50_ENV
     code =
-       sosend(asocket, (struct sockaddr *)saddr, &u, NULL, NULL, 0,
+       sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0,
               curthread);
-#else
-    code =
-       sosend(asocket, (struct sockaddr *)saddr, &u, NULL, NULL, 0, curproc);
-#endif
 #if KNET_DEBUG
     if (code) {
        if (code == EINVAL)
@@ -167,7 +174,7 @@ static void rxk_fasttimo(void);
 /* start intercepting basic calls */
 rxk_init()
 {
-    register struct protosw *tpro, *last;
+    struct protosw *tpro, *last;
     if (rxk_initDone)
        return 0;
 
@@ -197,12 +204,12 @@ static void
 rxk_input(struct mbuf *am, int iphlen)
 {
     void (*tproc) ();
-    register unsigned short *tsp;
+    unsigned short *tsp;
     int hdr;
     struct udphdr *tu;
-    register struct ip *ti;
+    struct ip *ti;
     struct udpiphdr *tvu;
-    register int i;
+    int i;
     char *phandle;
     afs_int32 code;
     struct sockaddr_in taddr;
@@ -347,7 +354,7 @@ rxk_fasttimo(void)
  * sometimes */
 static
 trysblock(sb)
-     register struct sockbuf *sb;
+     struct sockbuf *sb;
 {
     AFS_STATCNT(trysblock);
     if (sb->sb_flags & SB_LOCK) {
@@ -363,11 +370,11 @@ int
 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
            int nvec, afs_int32 asize, int istack)
 {
-    register struct mbuf *tm, *um;
-    register afs_int32 code;
+    struct mbuf *tm, *um;
+    afs_int32 code;
     int s;
     struct mbuf *top = 0;
-    register struct mbuf *m, **mp;
+    struct mbuf *m, **mp;
     int len;
     char *tdata;
     caddr_t tpa;
@@ -515,5 +522,3 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
     return code;
 }
 #endif
-
-#endif /* AFS_FBSD40_ENV */