svc_run.c revision 1.27.2.1 1 1.27.2.1 pgoyette /* $NetBSD: svc_run.c,v 1.27.2.1 2017/03/20 06:56:58 pgoyette Exp $ */
2 1.6 cgd
3 1.1 cgd /*
4 1.22 tron * Copyright (c) 2010, Oracle America, Inc.
5 1.22 tron *
6 1.22 tron * Redistribution and use in source and binary forms, with or without
7 1.22 tron * modification, are permitted provided that the following conditions are
8 1.22 tron * met:
9 1.22 tron *
10 1.22 tron * * Redistributions of source code must retain the above copyright
11 1.22 tron * notice, this list of conditions and the following disclaimer.
12 1.22 tron * * Redistributions in binary form must reproduce the above
13 1.22 tron * copyright notice, this list of conditions and the following
14 1.22 tron * disclaimer in the documentation and/or other materials
15 1.22 tron * provided with the distribution.
16 1.22 tron * * Neither the name of the "Oracle America, Inc." nor the names of its
17 1.22 tron * contributors may be used to endorse or promote products derived
18 1.22 tron * from this software without specific prior written permission.
19 1.22 tron *
20 1.22 tron * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 1.22 tron * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 1.22 tron * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 1.22 tron * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 1.22 tron * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 1.22 tron * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.22 tron * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 1.22 tron * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 1.22 tron * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 1.22 tron * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 1.22 tron * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 1.22 tron * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 cgd */
33 1.1 cgd
34 1.8 christos #include <sys/cdefs.h>
35 1.1 cgd #if defined(LIBC_SCCS) && !defined(lint)
36 1.8 christos #if 0
37 1.8 christos static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
38 1.8 christos static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";
39 1.8 christos #else
40 1.27.2.1 pgoyette __RCSID("$NetBSD: svc_run.c,v 1.27.2.1 2017/03/20 06:56:58 pgoyette Exp $");
41 1.8 christos #endif
42 1.1 cgd #endif
43 1.1 cgd
44 1.1 cgd /*
45 1.1 cgd * This is the rpc server side idle loop
46 1.1 cgd * Wait for input, call server program.
47 1.1 cgd */
48 1.9 jtc #include "namespace.h"
49 1.15 fvdl #include "reentrant.h"
50 1.12 lukem #include <err.h>
51 1.12 lukem #include <errno.h>
52 1.8 christos #include <stdio.h>
53 1.23 christos #include <stdlib.h>
54 1.16 thorpej #include <string.h>
55 1.12 lukem #include <unistd.h>
56 1.25 christos #include <poll.h>
57 1.12 lukem
58 1.11 lukem #include <rpc/rpc.h>
59 1.9 jtc
60 1.21 christos #include "svc_fdset.h"
61 1.18 fvdl #include "rpc_internal.h"
62 1.18 fvdl
63 1.9 jtc #ifdef __weak_alias
64 1.14 mycroft __weak_alias(svc_run,_svc_run)
65 1.15 fvdl __weak_alias(svc_exit,_svc_exit)
66 1.9 jtc #endif
67 1.3 deraadt
68 1.25 christos static void
69 1.25 christos svc_run_select(void)
70 1.1 cgd {
71 1.25 christos fd_set *readfds;
72 1.18 fvdl struct timeval timeout;
73 1.24 christos int *maxfd, fdsize;
74 1.21 christos #ifndef RUMP_RPC
75 1.21 christos int probs = 0;
76 1.21 christos #endif
77 1.19 thorpej #ifdef _REENTRANT
78 1.15 fvdl extern rwlock_t svc_fd_lock;
79 1.15 fvdl #endif
80 1.1 cgd
81 1.23 christos readfds = NULL;
82 1.23 christos fdsize = 0;
83 1.18 fvdl timeout.tv_sec = 30;
84 1.18 fvdl timeout.tv_usec = 0;
85 1.18 fvdl
86 1.1 cgd for (;;) {
87 1.15 fvdl rwlock_rdlock(&svc_fd_lock);
88 1.25 christos
89 1.25 christos maxfd = svc_fdset_getmax();
90 1.25 christos if (maxfd == NULL) {
91 1.25 christos warn("%s: can't get maxfd", __func__);
92 1.25 christos goto out;
93 1.25 christos }
94 1.25 christos
95 1.23 christos if (fdsize != svc_fdset_getsize(0)) {
96 1.23 christos fdsize = svc_fdset_getsize(0);
97 1.23 christos free(readfds);
98 1.23 christos readfds = svc_fdset_copy(svc_fdset_get());
99 1.25 christos if (readfds == NULL) {
100 1.25 christos warn("%s: can't copy fdset", __func__);
101 1.25 christos goto out;
102 1.25 christos }
103 1.25 christos } else
104 1.25 christos memcpy(readfds, svc_fdset_get(), __NFD_BYTES(fdsize));
105 1.25 christos
106 1.25 christos rwlock_unlock(&svc_fd_lock);
107 1.25 christos
108 1.25 christos switch (select(*maxfd + 1, readfds, NULL, NULL, &timeout)) {
109 1.25 christos case -1:
110 1.25 christos #ifndef RUMP_RPC
111 1.25 christos if ((errno == EINTR || errno == EBADF) && probs < 100) {
112 1.25 christos probs++;
113 1.25 christos continue;
114 1.25 christos }
115 1.25 christos #endif
116 1.25 christos if (errno == EINTR) {
117 1.25 christos continue;
118 1.25 christos }
119 1.25 christos warn("%s: select failed", __func__);
120 1.25 christos goto out;
121 1.25 christos case 0:
122 1.25 christos __svc_clean_idle(NULL, 30, FALSE);
123 1.25 christos continue;
124 1.25 christos default:
125 1.25 christos svc_getreqset2(readfds, fdsize);
126 1.25 christos #ifndef RUMP_RPC
127 1.25 christos probs = 0;
128 1.25 christos #endif
129 1.23 christos }
130 1.25 christos }
131 1.25 christos out:
132 1.25 christos free(readfds);
133 1.25 christos }
134 1.25 christos
135 1.25 christos static void
136 1.25 christos svc_run_poll(void)
137 1.25 christos {
138 1.25 christos struct pollfd *pfd;
139 1.25 christos int *maxfd, fdsize, i;
140 1.25 christos #ifndef RUMP_RPC
141 1.25 christos int probs = 0;
142 1.25 christos #endif
143 1.25 christos #ifdef _REENTRANT
144 1.25 christos extern rwlock_t svc_fd_lock;
145 1.25 christos #endif
146 1.25 christos
147 1.25 christos fdsize = 0;
148 1.25 christos pfd = NULL;
149 1.25 christos
150 1.25 christos for (;;) {
151 1.25 christos rwlock_rdlock(&svc_fd_lock);
152 1.25 christos
153 1.25 christos maxfd = svc_pollfd_getmax();
154 1.24 christos if (maxfd == NULL) {
155 1.24 christos warn("can't get maxfd");
156 1.25 christos goto out;
157 1.24 christos }
158 1.25 christos
159 1.27 christos if (pfd == NULL || fdsize != svc_pollfd_getsize(0)) {
160 1.25 christos fdsize = svc_fdset_getsize(0);
161 1.25 christos free(pfd);
162 1.25 christos pfd = svc_pollfd_copy(svc_pollfd_get());
163 1.25 christos if (pfd == NULL) {
164 1.25 christos warn("can't get pollfd");
165 1.25 christos goto out;
166 1.25 christos }
167 1.25 christos } else
168 1.25 christos memcpy(pfd, svc_pollfd_get(), *maxfd * sizeof(*pfd));
169 1.25 christos
170 1.15 fvdl rwlock_unlock(&svc_fd_lock);
171 1.25 christos
172 1.27.2.1 pgoyette switch ((i = poll(pfd, (nfds_t)*maxfd, 30 * 1000))) {
173 1.1 cgd case -1:
174 1.21 christos #ifndef RUMP_RPC
175 1.21 christos if ((errno == EINTR || errno == EBADF) && probs < 100) {
176 1.21 christos probs++;
177 1.21 christos continue;
178 1.21 christos }
179 1.21 christos #endif
180 1.1 cgd if (errno == EINTR) {
181 1.1 cgd continue;
182 1.1 cgd }
183 1.25 christos warn("%s: poll failed", __func__);
184 1.23 christos goto out;
185 1.1 cgd case 0:
186 1.25 christos __svc_clean_idle(NULL, 30, FALSE);
187 1.1 cgd continue;
188 1.1 cgd default:
189 1.25 christos svc_getreq_poll(pfd, i);
190 1.21 christos #ifndef RUMP_RPC
191 1.21 christos probs = 0;
192 1.21 christos #endif
193 1.1 cgd }
194 1.1 cgd }
195 1.23 christos out:
196 1.25 christos free(pfd);
197 1.25 christos }
198 1.25 christos
199 1.25 christos void
200 1.25 christos svc_run(void)
201 1.25 christos {
202 1.25 christos (__svc_flags & SVC_FDSET_POLL) ? svc_run_poll() : svc_run_select();
203 1.15 fvdl }
204 1.15 fvdl
205 1.15 fvdl /*
206 1.15 fvdl * This function causes svc_run() to exit by telling it that it has no
207 1.15 fvdl * more work to do.
208 1.15 fvdl */
209 1.15 fvdl void
210 1.20 christos svc_exit(void)
211 1.15 fvdl {
212 1.19 thorpej #ifdef _REENTRANT
213 1.15 fvdl extern rwlock_t svc_fd_lock;
214 1.15 fvdl #endif
215 1.15 fvdl
216 1.15 fvdl rwlock_wrlock(&svc_fd_lock);
217 1.23 christos svc_fdset_zero();
218 1.15 fvdl rwlock_unlock(&svc_fd_lock);
219 1.1 cgd }
220