Deleted Added
sdiff udiff text old ( 184877 ) new ( 193272 )
full compact
1/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */
2
3/*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or

--- 21 unchanged lines hidden (view full) ---

30 */
31
32#if defined(LIBC_SCCS) && !defined(lint)
33static char *sccsid2 = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
34static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";
35static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
36#endif
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/sys/rpc/clnt_vc.c 184877 2008-11-12 12:21:18Z dfr $");
39
40/*
41 * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
42 *
43 * Copyright (C) 1984, Sun Microsystems, Inc.
44 *
45 * TCP based RPC supports 'batched calls'.
46 * A sequence of calls may be batched-up in a send buffer. The rpc call

--- 39 unchanged lines hidden (view full) ---

86 rpcproc_t, struct mbuf *, struct mbuf **, struct timeval);
87static void clnt_vc_geterr(CLIENT *, struct rpc_err *);
88static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *);
89static void clnt_vc_abort(CLIENT *);
90static bool_t clnt_vc_control(CLIENT *, u_int, void *);
91static void clnt_vc_close(CLIENT *);
92static void clnt_vc_destroy(CLIENT *);
93static bool_t time_not_ok(struct timeval *);
94static void clnt_vc_soupcall(struct socket *so, void *arg, int waitflag);
95
96static struct clnt_ops clnt_vc_ops = {
97 .cl_call = clnt_vc_call,
98 .cl_abort = clnt_vc_abort,
99 .cl_geterr = clnt_vc_geterr,
100 .cl_freeres = clnt_vc_freeres,
101 .cl_close = clnt_vc_close,
102 .cl_destroy = clnt_vc_destroy,

--- 178 unchanged lines hidden (view full) ---

281 cl->cl_ops = &clnt_vc_ops;
282 cl->cl_private = ct;
283 cl->cl_auth = authnone_create();
284 sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
285 recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
286 soreserve(ct->ct_socket, sendsz, recvsz);
287
288 SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
289 ct->ct_socket->so_upcallarg = ct;
290 ct->ct_socket->so_upcall = clnt_vc_soupcall;
291 ct->ct_socket->so_rcv.sb_flags |= SB_UPCALL;
292 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
293
294 ct->ct_record = NULL;
295 ct->ct_record_resid = 0;
296 TAILQ_INIT(&ct->ct_pending);
297 return (cl);
298
299err:

--- 445 unchanged lines hidden (view full) ---

745 while (ct->ct_closing)
746 msleep(ct, &ct->ct_lock, 0, "rpcclose", 0);
747 KASSERT(ct->ct_closed, ("client should be closed"));
748 mtx_unlock(&ct->ct_lock);
749 return;
750 }
751
752 if (ct->ct_socket) {
753 SOCKBUF_LOCK(&ct->ct_socket->so_rcv);
754 ct->ct_socket->so_upcallarg = NULL;
755 ct->ct_socket->so_upcall = NULL;
756 ct->ct_socket->so_rcv.sb_flags &= ~SB_UPCALL;
757 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
758
759 /*
760 * Abort any pending requests and wait until everyone
761 * has finished with clnt_vc_call.
762 */
763 ct->ct_closing = TRUE;
764 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) {
765 cr->cr_xid = 0;
766 cr->cr_error = ESHUTDOWN;
767 wakeup(cr);
768 }
769
770 while (ct->ct_threads)
771 msleep(ct, &ct->ct_lock, 0, "rpcclose", 0);

--- 38 unchanged lines hidden (view full) ---

810 */
811static bool_t
812time_not_ok(struct timeval *t)
813{
814 return (t->tv_sec <= -1 || t->tv_sec > 100000000 ||
815 t->tv_usec <= -1 || t->tv_usec > 1000000);
816}
817
818void
819clnt_vc_soupcall(struct socket *so, void *arg, int waitflag)
820{
821 struct ct_data *ct = (struct ct_data *) arg;
822 struct uio uio;
823 struct mbuf *m;
824 struct ct_request *cr;
825 int error, rcvflag, foundreq;
826 uint32_t xid, header;

--- 8 unchanged lines hidden (view full) ---

835 if (ct->ct_record_resid == 0) {
836
837 /*
838 * Make sure there is either a whole record
839 * mark in the buffer or there is some other
840 * error condition
841 */
842 do_read = FALSE;
843 SOCKBUF_LOCK(&so->so_rcv);
844 if (so->so_rcv.sb_cc >= sizeof(uint32_t)
845 || (so->so_rcv.sb_state & SBS_CANTRCVMORE)
846 || so->so_error)
847 do_read = TRUE;
848 SOCKBUF_UNLOCK(&so->so_rcv);
849
850 if (!do_read)
851 return;
852
853 uio.uio_resid = sizeof(uint32_t);
854 m = NULL;
855 rcvflag = MSG_DONTWAIT | MSG_SOCALLBCK;
856 error = soreceive(so, NULL, &uio, &m, NULL, &rcvflag);
857
858 if (error == EWOULDBLOCK)
859 break;
860
861 /*
862 * If there was an error, wake up all pending
863 * requests.
864 */

--- 23 unchanged lines hidden (view full) ---

888 ct->ct_record_eor = ((header & 0x80000000) != 0);
889 m_freem(m);
890 } else {
891 /*
892 * Wait until the socket has the whole record
893 * buffered.
894 */
895 do_read = FALSE;
896 SOCKBUF_LOCK(&so->so_rcv);
897 if (so->so_rcv.sb_cc >= ct->ct_record_resid
898 || (so->so_rcv.sb_state & SBS_CANTRCVMORE)
899 || so->so_error)
900 do_read = TRUE;
901 SOCKBUF_UNLOCK(&so->so_rcv);
902
903 if (!do_read)
904 return;
905
906 /*
907 * We have the record mark. Read as much as
908 * the socket has buffered up to the end of
909 * this record.
910 */
911 uio.uio_resid = ct->ct_record_resid;
912 m = NULL;
913 rcvflag = MSG_DONTWAIT | MSG_SOCALLBCK;
914 error = soreceive(so, NULL, &uio, &m, NULL, &rcvflag);
915
916 if (error == EWOULDBLOCK)
917 break;
918
919 if (error || uio.uio_resid == ct->ct_record_resid)
920 goto wakeup_all;
921
922 /*

--- 52 unchanged lines hidden (view full) ---

975 mtx_unlock(&ct->ct_lock);
976
977 if (!foundreq)
978 m_freem(ct->ct_record);
979 ct->ct_record = NULL;
980 }
981 }
982 } while (m);
983}