7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <sys/signal.h>
35 #include <sys/stat.h>
36 #include <sys/proc.h>
37 #include <sys/cred.h>
38 #include <sys/user.h>
39 #include <sys/vnode.h>
40 #include <sys/file.h>
41 #include <sys/stream.h>
42 #include <sys/strsubr.h>
43 #include <sys/stropts.h>
44 #include <sys/tihdr.h>
45 #include <sys/var.h>
46 #include <sys/poll.h>
47 #include <sys/termio.h>
8157
8158 /*
8159 * Determines whether the necessary conditions are set on a stream
8160 * for it to be readable, writeable, or have exceptions.
8161 *
8162 * strpoll handles the consolidation private events:
8163 * POLLNOERR Do not return POLLERR even if there are stream
8164 * head errors.
8165 * Used by sockfs.
8166 * POLLRDDATA Do not return POLLIN unless at least one message on
8167 * the queue contains one or more M_DATA mblks. Thus
8168 * when this flag is set a queue with only
8169 * M_PROTO/M_PCPROTO mblks does not return POLLIN.
8170 * Used by sockfs to ignore T_EXDATA_IND messages.
8171 *
8172 * Note: POLLRDDATA assumes that synch streams only return messages with
8173 * an M_DATA attached (i.e. not messages consisting of only
8174 * an M_PROTO/M_PCPROTO part).
8175 */
8176 int
8177 strpoll(
8178 struct stdata *stp,
8179 short events_arg,
8180 int anyyet,
8181 short *reventsp,
8182 struct pollhead **phpp)
8183 {
8184 int events = (ushort_t)events_arg;
8185 int retevents = 0;
8186 mblk_t *mp;
8187 qband_t *qbp;
8188 long sd_flags = stp->sd_flag;
8189 int headlocked = 0;
8190
8191 /*
8192 * For performance, a single 'if' tests for most possible edge
8193 * conditions in one shot
8194 */
8195 if (sd_flags & (STPLEX | STRDERR | STWRERR)) {
8196 if (sd_flags & STPLEX) {
8197 *reventsp = POLLNVAL;
8198 return (EINVAL);
8199 }
8200 if (((events & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) &&
8201 (sd_flags & STRDERR)) ||
8299 * find an M_DATA.
8300 */
8301 if ((events & POLLRDDATA) &&
8302 mp->b_datap->db_type != M_DATA) {
8303 mblk_t *nmp = mp->b_cont;
8304
8305 while (nmp != NULL &&
8306 nmp->b_datap->db_type != M_DATA)
8307 nmp = nmp->b_cont;
8308 if (nmp == NULL) {
8309 mp = mp->b_next;
8310 continue;
8311 }
8312 }
8313 if (mp->b_band == 0)
8314 retevents |= normevents;
8315 else
8316 retevents |= (events & (POLLIN | POLLRDBAND));
8317 break;
8318 }
8319 if (! (retevents & normevents) &&
8320 (stp->sd_wakeq & RSLEEP)) {
8321 /*
8322 * Sync stream barrier read queue has data.
8323 */
8324 retevents |= normevents;
8325 }
8326 /* Treat eof as normal data */
8327 if (sd_flags & STREOF)
8328 retevents |= normevents;
8329 }
8330
8331 *reventsp = (short)retevents;
8332 if (retevents && !(events & POLLET)) {
8333 if (headlocked)
8334 mutex_exit(&stp->sd_lock);
8335 return (0);
8336 }
8337
8338 /*
8339 * If poll() has not found any events yet, set up event cell
8340 * to wake up the poll if a requested event occurs on this
8341 * stream. Check for collisions with outstanding poll requests.
8342 */
8343 if (!anyyet) {
8344 *phpp = &stp->sd_pollist;
8345 if (headlocked == 0) {
8346 if (polllock(&stp->sd_pollist, &stp->sd_lock) != 0) {
8347 *reventsp = POLLNVAL;
8348 return (0);
8349 }
8350 headlocked = 1;
8351 }
8352 stp->sd_rput_opt |= SR_POLLIN;
8353 }
8354 if (headlocked)
8355 mutex_exit(&stp->sd_lock);
8356 return (0);
8357 }
8358
8359 /*
8360 * The purpose of putback() is to assure sleeping polls/reads
8361 * are awakened when there are no new messages arriving at the,
8362 * stream head, and a message is placed back on the read queue.
8363 *
8364 * sd_lock must be held when messages are placed back on stream
8365 * head. (getq() holds sd_lock when it removes messages from
8366 * the queue)
8367 */
8368
8369 static void
8370 putback(struct stdata *stp, queue_t *q, mblk_t *bp, int band)
8371 {
8372 mblk_t *qfirst;
8373 ASSERT(MUTEX_HELD(&stp->sd_lock));
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24
25 /*
26 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Copyright 2017 Joyent, Inc.
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <sys/signal.h>
35 #include <sys/stat.h>
36 #include <sys/proc.h>
37 #include <sys/cred.h>
38 #include <sys/user.h>
39 #include <sys/vnode.h>
40 #include <sys/file.h>
41 #include <sys/stream.h>
42 #include <sys/strsubr.h>
43 #include <sys/stropts.h>
44 #include <sys/tihdr.h>
45 #include <sys/var.h>
46 #include <sys/poll.h>
47 #include <sys/termio.h>
8157
8158 /*
8159 * Determines whether the necessary conditions are set on a stream
8160 * for it to be readable, writeable, or have exceptions.
8161 *
8162 * strpoll handles the consolidation private events:
8163 * POLLNOERR Do not return POLLERR even if there are stream
8164 * head errors.
8165 * Used by sockfs.
8166 * POLLRDDATA Do not return POLLIN unless at least one message on
8167 * the queue contains one or more M_DATA mblks. Thus
8168 * when this flag is set a queue with only
8169 * M_PROTO/M_PCPROTO mblks does not return POLLIN.
8170 * Used by sockfs to ignore T_EXDATA_IND messages.
8171 *
8172 * Note: POLLRDDATA assumes that synch streams only return messages with
8173 * an M_DATA attached (i.e. not messages consisting of only
8174 * an M_PROTO/M_PCPROTO part).
8175 */
8176 int
8177 strpoll(struct stdata *stp, short events_arg, int anyyet, short *reventsp,
8178 struct pollhead **phpp)
8179 {
8180 int events = (ushort_t)events_arg;
8181 int retevents = 0;
8182 mblk_t *mp;
8183 qband_t *qbp;
8184 long sd_flags = stp->sd_flag;
8185 int headlocked = 0;
8186
8187 /*
8188 * For performance, a single 'if' tests for most possible edge
8189 * conditions in one shot
8190 */
8191 if (sd_flags & (STPLEX | STRDERR | STWRERR)) {
8192 if (sd_flags & STPLEX) {
8193 *reventsp = POLLNVAL;
8194 return (EINVAL);
8195 }
8196 if (((events & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) &&
8197 (sd_flags & STRDERR)) ||
8295 * find an M_DATA.
8296 */
8297 if ((events & POLLRDDATA) &&
8298 mp->b_datap->db_type != M_DATA) {
8299 mblk_t *nmp = mp->b_cont;
8300
8301 while (nmp != NULL &&
8302 nmp->b_datap->db_type != M_DATA)
8303 nmp = nmp->b_cont;
8304 if (nmp == NULL) {
8305 mp = mp->b_next;
8306 continue;
8307 }
8308 }
8309 if (mp->b_band == 0)
8310 retevents |= normevents;
8311 else
8312 retevents |= (events & (POLLIN | POLLRDBAND));
8313 break;
8314 }
8315 if (!(retevents & normevents) && (stp->sd_wakeq & RSLEEP)) {
8316 /*
8317 * Sync stream barrier read queue has data.
8318 */
8319 retevents |= normevents;
8320 }
8321 /* Treat eof as normal data */
8322 if (sd_flags & STREOF)
8323 retevents |= normevents;
8324 }
8325
8326 /*
8327 * Pass back a pollhead if no events are pending or if edge-triggering
8328 * has been configured on this resource.
8329 */
8330 if ((retevents == 0 && !anyyet) || (events & POLLET)) {
8331 *phpp = &stp->sd_pollist;
8332 if (headlocked == 0) {
8333 if (polllock(&stp->sd_pollist, &stp->sd_lock) != 0) {
8334 *reventsp = POLLNVAL;
8335 return (0);
8336 }
8337 headlocked = 1;
8338 }
8339 stp->sd_rput_opt |= SR_POLLIN;
8340 }
8341
8342 *reventsp = (short)retevents;
8343 if (headlocked)
8344 mutex_exit(&stp->sd_lock);
8345 return (0);
8346 }
8347
8348 /*
8349 * The purpose of putback() is to assure sleeping polls/reads
8350 * are awakened when there are no new messages arriving at the,
8351 * stream head, and a message is placed back on the read queue.
8352 *
8353 * sd_lock must be held when messages are placed back on stream
8354 * head. (getq() holds sd_lock when it removes messages from
8355 * the queue)
8356 */
8357
8358 static void
8359 putback(struct stdata *stp, queue_t *q, mblk_t *bp, int band)
8360 {
8361 mblk_t *qfirst;
8362 ASSERT(MUTEX_HELD(&stp->sd_lock));
|