Deleted Added
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 $");
38__FBSDID("$FreeBSD: head/sys/rpc/clnt_vc.c 193272 2009-06-01 21:17:03Z jhb $");
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);
94static int 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;
289 soupcall_set(ct->ct_socket, SO_RCV, clnt_vc_soupcall, ct);
290 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv);
291
292 ct->ct_record = NULL;
293 ct->ct_record_resid = 0;
294 TAILQ_INIT(&ct->ct_pending);
295 return (cl);
296
297err:

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

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

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

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

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

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

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

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

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

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