sys_pipe.c (86598) | sys_pipe.c (89306) |
---|---|
1/* 2 * Copyright (c) 1996 John S. Dyson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Absolutely no warranty of function or purpose is made by the author 15 * John S. Dyson. 16 * 4. Modifications may be freely made to this file if the above conditions 17 * are met. 18 * | 1/* 2 * Copyright (c) 1996 John S. Dyson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Absolutely no warranty of function or purpose is made by the author 15 * John S. Dyson. 16 * 4. Modifications may be freely made to this file if the above conditions 17 * are met. 18 * |
19 * $FreeBSD: head/sys/kern/sys_pipe.c 86598 2001-11-19 09:25:30Z sobomax $ | 19 * $FreeBSD: head/sys/kern/sys_pipe.c 89306 2002-01-13 11:58:06Z alfred $ |
20 */ 21 22/* 23 * This file contains a high-performance replacement for the socket-based 24 * pipes scheme originally used in FreeBSD/4.4Lite. It does not support 25 * all features of sockets, but does do everything that pipes normally 26 * do. 27 */ --- 172 unchanged lines hidden (view full) --- 200 td->td_retval[0] = fd; 201 202 /* 203 * Warning: once we've gotten past allocation of the fd for the 204 * read-side, we can only drop the read side via fdrop() in order 205 * to avoid races against processes which manage to dup() the read 206 * side while we are blocked trying to allocate the write side. 207 */ | 20 */ 21 22/* 23 * This file contains a high-performance replacement for the socket-based 24 * pipes scheme originally used in FreeBSD/4.4Lite. It does not support 25 * all features of sockets, but does do everything that pipes normally 26 * do. 27 */ --- 172 unchanged lines hidden (view full) --- 200 td->td_retval[0] = fd; 201 202 /* 203 * Warning: once we've gotten past allocation of the fd for the 204 * read-side, we can only drop the read side via fdrop() in order 205 * to avoid races against processes which manage to dup() the read 206 * side while we are blocked trying to allocate the write side. 207 */ |
208 FILE_LOCK(rf); |
|
208 rf->f_flag = FREAD | FWRITE; 209 rf->f_type = DTYPE_PIPE; 210 rf->f_data = (caddr_t)rpipe; 211 rf->f_ops = &pipeops; | 209 rf->f_flag = FREAD | FWRITE; 210 rf->f_type = DTYPE_PIPE; 211 rf->f_data = (caddr_t)rpipe; 212 rf->f_ops = &pipeops; |
213 FILE_UNLOCK(rf); |
|
212 error = falloc(td, &wf, &fd); 213 if (error) { | 214 error = falloc(td, &wf, &fd); 215 if (error) { |
216 FILEDESC_LOCK(fdp); |
|
214 if (fdp->fd_ofiles[td->td_retval[0]] == rf) { 215 fdp->fd_ofiles[td->td_retval[0]] = NULL; | 217 if (fdp->fd_ofiles[td->td_retval[0]] == rf) { 218 fdp->fd_ofiles[td->td_retval[0]] = NULL; |
219 FILEDESC_UNLOCK(fdp); |
|
216 fdrop(rf, td); | 220 fdrop(rf, td); |
217 } | 221 } else 222 FILEDESC_UNLOCK(fdp); |
218 fdrop(rf, td); 219 /* rpipe has been closed by fdrop(). */ 220 pipeclose(wpipe); 221 return (error); 222 } | 223 fdrop(rf, td); 224 /* rpipe has been closed by fdrop(). */ 225 pipeclose(wpipe); 226 return (error); 227 } |
228 FILE_LOCK(wf); |
|
223 wf->f_flag = FREAD | FWRITE; 224 wf->f_type = DTYPE_PIPE; 225 wf->f_data = (caddr_t)wpipe; 226 wf->f_ops = &pipeops; | 229 wf->f_flag = FREAD | FWRITE; 230 wf->f_type = DTYPE_PIPE; 231 wf->f_data = (caddr_t)wpipe; 232 wf->f_ops = &pipeops; |
233 FILE_UNLOCK(wf); |
|
227 td->td_retval[1] = fd; | 234 td->td_retval[1] = fd; |
228 | |
229 rpipe->pipe_peer = wpipe; 230 wpipe->pipe_peer = rpipe; 231 fdrop(rf, td); 232 233 return (0); 234} 235 236/* --- 253 unchanged lines hidden (view full) --- 490 * relock to loop. 491 */ 492 pipeunlock(rpipe); 493 494 /* 495 * Handle non-blocking mode operation or 496 * wait for more data. 497 */ | 235 rpipe->pipe_peer = wpipe; 236 wpipe->pipe_peer = rpipe; 237 fdrop(rf, td); 238 239 return (0); 240} 241 242/* --- 253 unchanged lines hidden (view full) --- 496 * relock to loop. 497 */ 498 pipeunlock(rpipe); 499 500 /* 501 * Handle non-blocking mode operation or 502 * wait for more data. 503 */ |
504 FILE_LOCK(fp); |
|
498 if (fp->f_flag & FNONBLOCK) { | 505 if (fp->f_flag & FNONBLOCK) { |
506 FILE_UNLOCK(fp); |
|
499 error = EAGAIN; 500 } else { | 507 error = EAGAIN; 508 } else { |
509 FILE_UNLOCK(fp); |
|
501 rpipe->pipe_state |= PIPE_WANTR; 502 if ((error = tsleep(rpipe, PRIBIO | PCATCH, 503 "piperd", 0)) == 0) 504 error = pipelock(rpipe, 1); 505 } 506 if (error) 507 goto unlocked_error; 508 } --- 311 unchanged lines hidden (view full) --- 820 * If the transfer is large, we can gain performance if 821 * we do process-to-process copies directly. 822 * If the write is non-blocking, we don't use the 823 * direct write mechanism. 824 * 825 * The direct write mechanism will detect the reader going 826 * away on us. 827 */ | 510 rpipe->pipe_state |= PIPE_WANTR; 511 if ((error = tsleep(rpipe, PRIBIO | PCATCH, 512 "piperd", 0)) == 0) 513 error = pipelock(rpipe, 1); 514 } 515 if (error) 516 goto unlocked_error; 517 } --- 311 unchanged lines hidden (view full) --- 829 * If the transfer is large, we can gain performance if 830 * we do process-to-process copies directly. 831 * If the write is non-blocking, we don't use the 832 * direct write mechanism. 833 * 834 * The direct write mechanism will detect the reader going 835 * away on us. 836 */ |
837 FILE_LOCK(fp); |
|
828 if ((uio->uio_iov->iov_len >= PIPE_MINDIRECT) && 829 (fp->f_flag & FNONBLOCK) == 0 && 830 (wpipe->pipe_map.kva || (amountpipekva < LIMITPIPEKVA)) && 831 (uio->uio_iov->iov_len >= PIPE_MINDIRECT)) { | 838 if ((uio->uio_iov->iov_len >= PIPE_MINDIRECT) && 839 (fp->f_flag & FNONBLOCK) == 0 && 840 (wpipe->pipe_map.kva || (amountpipekva < LIMITPIPEKVA)) && 841 (uio->uio_iov->iov_len >= PIPE_MINDIRECT)) { |
842 FILE_UNLOCK(fp); |
|
832 error = pipe_direct_write( wpipe, uio); 833 if (error) 834 break; 835 continue; | 843 error = pipe_direct_write( wpipe, uio); 844 if (error) 845 break; 846 continue; |
836 } | 847 } else 848 FILE_UNLOCK(fp); |
837#endif 838 839 /* 840 * Pipe buffered writes cannot be coincidental with 841 * direct writes. We wait until the currently executing 842 * direct write is completed before we start filling the 843 * pipe buffer. We break out if a signal occurs or the 844 * reader goes away. --- 111 unchanged lines hidden (view full) --- 956 if (wpipe->pipe_state & PIPE_WANTR) { 957 wpipe->pipe_state &= ~PIPE_WANTR; 958 wakeup(wpipe); 959 } 960 961 /* 962 * don't block on non-blocking I/O 963 */ | 849#endif 850 851 /* 852 * Pipe buffered writes cannot be coincidental with 853 * direct writes. We wait until the currently executing 854 * direct write is completed before we start filling the 855 * pipe buffer. We break out if a signal occurs or the 856 * reader goes away. --- 111 unchanged lines hidden (view full) --- 968 if (wpipe->pipe_state & PIPE_WANTR) { 969 wpipe->pipe_state &= ~PIPE_WANTR; 970 wakeup(wpipe); 971 } 972 973 /* 974 * don't block on non-blocking I/O 975 */ |
976 FILE_LOCK(fp); |
|
964 if (fp->f_flag & FNONBLOCK) { | 977 if (fp->f_flag & FNONBLOCK) { |
978 FILE_UNLOCK(fp); |
|
965 error = EAGAIN; 966 break; 967 } | 979 error = EAGAIN; 980 break; 981 } |
982 FILE_UNLOCK(fp); |
|
968 969 /* 970 * We have no more space and have something to offer, 971 * wake up select/poll. 972 */ 973 pipeselwakeup(wpipe); 974 975 wpipe->pipe_state |= PIPE_WANTW; --- 255 unchanged lines hidden (view full) --- 1231 zfree(pipe_zone, cpipe); 1232 } 1233} 1234 1235/*ARGSUSED*/ 1236static int 1237pipe_kqfilter(struct file *fp, struct knote *kn) 1238{ | 983 984 /* 985 * We have no more space and have something to offer, 986 * wake up select/poll. 987 */ 988 pipeselwakeup(wpipe); 989 990 wpipe->pipe_state |= PIPE_WANTW; --- 255 unchanged lines hidden (view full) --- 1246 zfree(pipe_zone, cpipe); 1247 } 1248} 1249 1250/*ARGSUSED*/ 1251static int 1252pipe_kqfilter(struct file *fp, struct knote *kn) 1253{ |
1239 struct pipe *cpipe = (struct pipe *)kn->kn_fp->f_data; | 1254 struct pipe *cpipe; |
1240 | 1255 |
1256 cpipe = (struct pipe *)kn->kn_fp->f_data; |
|
1241 switch (kn->kn_filter) { 1242 case EVFILT_READ: 1243 kn->kn_fop = &pipe_rfiltops; 1244 break; 1245 case EVFILT_WRITE: 1246 kn->kn_fop = &pipe_wfiltops; 1247 cpipe = cpipe->pipe_peer; 1248 break; --- 54 unchanged lines hidden --- | 1257 switch (kn->kn_filter) { 1258 case EVFILT_READ: 1259 kn->kn_fop = &pipe_rfiltops; 1260 break; 1261 case EVFILT_WRITE: 1262 kn->kn_fop = &pipe_wfiltops; 1263 cpipe = cpipe->pipe_peer; 1264 break; --- 54 unchanged lines hidden --- |