darwin-use-kthreads-20060117
[openafs.git] / src / rx / DARWIN / rx_knet.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 RCSID
14     ("$Header$");
15
16 #include "rx/rx_kcommon.h"
17
18 #ifdef AFS_DARWIN80_ENV
19 #define soclose sock_close
20 #endif
21  
22 int
23 osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
24                int nvecs, int *alength)
25 {
26 #ifdef AFS_DARWIN80_ENV
27     socket_t asocket = (socket_t)so;
28     struct msghdr msg;
29     struct sockaddr_storage ss;
30     int rlen;
31     mbuf_t m;
32 #else
33     struct socket *asocket = (struct socket *)so;
34     struct uio u;
35 #endif
36     int i;
37     struct iovec iov[RX_MAXIOVECS];
38     struct sockaddr *sa = NULL;
39     int code;
40     size_t resid;
41
42     int haveGlock = ISAFS_GLOCK();
43     /*AFS_STATCNT(osi_NetReceive); */
44
45     if (nvecs > RX_MAXIOVECS)
46         osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
47
48     for (i = 0; i < nvecs; i++)
49         iov[i] = dvec[i];
50     if (haveGlock)
51         AFS_GUNLOCK();
52 #if defined(KERNEL_FUNNEL)
53     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
54 #endif
55 #ifdef AFS_DARWIN80_ENV
56 #if 1
57     resid = *alength;
58     memset(&msg, 0, sizeof(struct msghdr));
59     msg.msg_name = &ss;
60     msg.msg_namelen = sizeof(struct sockaddr_storage);
61     sa =(struct sockaddr *) &ss;
62     code = sock_receivembuf(asocket, &msg, &m, 0, alength);
63     if (!code) {
64         size_t offset=0,sz;
65         resid = *alength;
66         for (i=0;i<nvecs && resid;i++) {
67             sz=MIN(resid, iov[i].iov_len);
68             code = mbuf_copydata(m, offset, sz, iov[i].iov_base);
69             if (code)
70                 break;
71             resid-=sz;
72             offset+=sz;
73         }
74     }
75     mbuf_freem(m);
76 #else
77     resid = *alength;
78     printf("Want to read %d bytes...", resid);
79     for (i=0; i < nvecs && resid; i++) {
80        if (resid < iov[i].iov_len)
81           iov[0].iov_len = resid;
82        resid -= iov[i].iov_len;
83     }
84     printf("Using %d/%d iovs\n", i, nvecs);
85     nvecs = i;
86     rlen = 0;
87     memset(&msg, 0, sizeof(struct msghdr));
88     msg.msg_name = &ss;
89     msg.msg_namelen = sizeof(struct sockaddr_storage);
90     msg.msg_iov = &iov[0];
91     msg.msg_iovlen = nvecs;
92     sa =(struct sockaddr_in *) &ss;
93     code = sock_receive(asocket, &msg, 0, &rlen);
94     resid = *alength;
95     if (resid != rlen)
96     printf("recieved %d bytes\n", rlen);
97     if (resid > rlen)
98        resid -= rlen;
99     else
100        resid = 0;
101 #endif
102 #else
103
104     u.uio_iov = &iov[0];
105     u.uio_iovcnt = nvecs;
106     u.uio_offset = 0;
107     u.uio_resid = *alength;
108     u.uio_segflg = UIO_SYSSPACE;
109     u.uio_rw = UIO_READ;
110     u.uio_procp = NULL;
111     code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
112     resid = u.uio_resid;
113 #endif
114
115 #if defined(KERNEL_FUNNEL)
116     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
117 #endif
118     if (haveGlock)
119         AFS_GLOCK();
120
121     if (code)
122         return code;
123     *alength -= resid;
124     if (sa) {
125         if (sa->sa_family == AF_INET) {
126             if (addr)
127                 *addr = *(struct sockaddr_in *)sa;
128         } else
129             printf("Unknown socket family %d in NetReceive\n", sa->sa_family);
130         FREE(sa, M_SONAME);
131     }
132     return code;
133 }
134
135 extern int rxk_ListenerPid;
136 void
137 osi_StopListener(void)
138 {
139     struct proc *p;
140
141 #if defined(KERNEL_FUNNEL)
142     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
143 #endif
144     soclose(rx_socket);
145 #if defined(KERNEL_FUNNEL)
146     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
147 #endif
148 #ifndef AFS_DARWIN80_ENV
149     p = pfind(rxk_ListenerPid);
150     if (p)
151         psignal(p, SIGUSR1);
152 #endif
153 }
154
155 int
156 osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
157             int nvecs, afs_int32 alength, int istack)
158 {
159 #ifdef AFS_DARWIN80_ENV
160     socket_t asocket = (socket_t)so;
161     struct msghdr msg;
162     size_t slen;
163 #else
164     struct socket *asocket = (struct socket *)so;
165     struct uio u;
166 #endif
167     register afs_int32 code;
168     int i;
169     struct iovec iov[RX_MAXIOVECS];
170     int haveGlock = ISAFS_GLOCK();
171
172     AFS_STATCNT(osi_NetSend);
173     if (nvecs > RX_MAXIOVECS)
174         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
175
176     for (i = 0; i < nvecs; i++)
177         iov[i] = dvec[i];
178
179     addr->sin_len = sizeof(struct sockaddr_in);
180
181     if (haveGlock)
182         AFS_GUNLOCK();
183 #if defined(KERNEL_FUNNEL)
184     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
185 #endif
186 #ifdef AFS_DARWIN80_ENV
187     memset(&msg, 0, sizeof(struct msghdr));
188     msg.msg_name = addr;
189     msg.msg_namelen = ((struct sockaddr *)addr)->sa_len;
190     msg.msg_iov = &iov[0];
191     msg.msg_iovlen = nvecs;
192     code = sock_send(asocket, &msg, 0, &slen);
193 #else
194     u.uio_iov = &iov[0];
195     u.uio_iovcnt = nvecs;
196     u.uio_offset = 0;
197     u.uio_resid = alength;
198     u.uio_segflg = UIO_SYSSPACE;
199     u.uio_rw = UIO_WRITE;
200     u.uio_procp = NULL;
201     code = sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0);
202 #endif
203
204 #if defined(KERNEL_FUNNEL)
205     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
206 #endif
207     if (haveGlock)
208         AFS_GLOCK();
209     return code;
210 }