Project

General

Profile

Bug #1056 » ksocket_unix.patch

Stepan Zastupov, 2011-09-30 01:58 PM

View differences:

usr/src/uts/common/io/ksocket/ksocket.c Thu Sep 22 13:37:45 2011 +0400 → usr/src/uts/common/io/ksocket/ksocket.c Fri Sep 30 16:31:38 2011 +0400
20 20
 */
21 21

  
22 22
/*
23
 * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23 24
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 25
 */
25 26

  
......
30 31
#include <sys/sysmacros.h>
31 32
#include <sys/filio.h>		/* FIO* ioctls */
32 33
#include <sys/sockio.h>		/* SIOC* ioctls */
34
#include <sys/poll_impl.h>
33 35
#include <sys/cmn_err.h>
34 36
#include <sys/ksocket.h>
35 37
#include <io/ksocket/ksocket_impl.h>
......
54 56
	/* All Solaris components should pass a cred for this operation. */
55 57
	ASSERT(cr != NULL);
56 58

  
57
	if (domain == AF_NCA || domain == AF_UNIX)
59
	if (domain == AF_NCA)
58 60
		return (EAFNOSUPPORT);
59 61

  
60 62
	ASSERT(flags == KSOCKET_SLEEP || flags == KSOCKET_NOSLEEP);
......
717 719
	return (rval);
718 720
}
719 721

  
722
/*
723
 * Wait for an input event, similar to t_kspoll().
724
 * Ideas and code borrowed from ../devpoll.c
725
 * Basically, setup just enough poll data structures so
726
 * we can block on a CV until timeout or pollwakeup().
727
 */
728
int
729
ksocket_spoll(ksocket_t ks, int timo, short events, short *revents,
730
    struct cred *cr)
731
{
732
	struct		sonode *so;
733
	pollhead_t	*php, *php2;
734
	polldat_t	*pdp;
735
	pollcache_t	*pcp;
736
	int		error;
737
	clock_t		expires = 0;
738
	clock_t		rval;
739

  
740
	/* All Solaris components should pass a cred for this operation. */
741
	ASSERT(cr != NULL);
742
	ASSERT(curthread->t_pollcache == NULL);
743

  
744
	if (revents == NULL)
745
		return (EINVAL);
746
	if (!KSOCKET_VALID(ks))
747
		return (ENOTSOCK);
748
	so = KSTOSO(ks);
749

  
750
	/*
751
	 * Check if there are any events already pending.
752
	 * If we're not willing to block, (timo == 0) then
753
	 * pass "anyyet">0 to socket_poll so it can skip
754
	 * some work.  Othewise pass "anyyet"=0 and if
755
	 * there are no events pending, it will fill in
756
	 * the pollhead pointer we need for pollwakeup().
757
	 *
758
	 * XXX - pollrelock() logic needs to know which
759
	 * which pollcache lock to grab. It'd be a
760
	 * cleaner solution if we could pass pcp as
761
	 * an arguement in VOP_POLL interface instead
762
	 * of implicitly passing it using thread_t
763
	 * struct. On the other hand, changing VOP_POLL
764
	 * interface will require all driver/file system
765
	 * poll routine to change. May want to revisit
766
	 * the tradeoff later.
767
	 */
768
	php = NULL;
769
	*revents = 0;
770
	pcp = pcache_alloc();
771
	pcache_create(pcp, 1);
772

  
773
	mutex_enter(&pcp->pc_lock);
774
	curthread->t_pollcache = pcp;
775
	error = socket_poll(so, (short)events, (timo == 0),
776
	    revents, &php);
777
	curthread->t_pollcache = NULL;
778
	mutex_exit(&pcp->pc_lock);
779

  
780
	if (error != 0 || *revents != 0 || timo == 0)
781
		goto out;
782

  
783
	/*
784
	 * Need to block.  Did not get *revents, so the
785
	 * php should be non-NULL, but let's verify.
786
	 * Also compute when our sleep expires.
787
	 */
788
	if (php == NULL) {
789
		error = EIO;
790
		goto out;
791
	}
792
	if (timo > 0)
793
		expires = ddi_get_lbolt() +
794
		    MSEC_TO_TICK_ROUNDUP(timo);
795

  
796
	/*
797
	 * Setup: pollhead -> polldat -> pollcache
798
	 * needed for pollwakeup()
799
	 */
800
	pdp = kmem_zalloc(sizeof (*pdp), KM_SLEEP);
801
	pdp->pd_fd = 0;
802
	pdp->pd_events = events;
803
	pdp->pd_pcache = pcp;
804
	pcache_insert_fd(pcp, pdp, 1);
805
	pollhead_insert(php, pdp);
806
	pdp->pd_php = php;
807

  
808
	mutex_enter(&pcp->pc_lock);
809
	while (!(so->so_state & SS_CLOSING)) {
810
		pcp->pc_flag = 0;
811

  
812
		/* Ditto pcp comment above. */
813
		curthread->t_pollcache = pcp;
814
		error = socket_poll(so, (short)events, 0,
815
		    revents, &php2);
816
		curthread->t_pollcache = NULL;
817
		ASSERT(php2 == php);
818

  
819
		if (error != 0 || *revents != 0)
820
			break;
821

  
822
		if (pcp->pc_flag & T_POLLWAKE)
823
			continue;
824

  
825
		if (timo == -1) {
826
			rval = cv_wait_sig(&pcp->pc_cv, &pcp->pc_lock);
827
		} else {
828
			rval = cv_timedwait_sig(&pcp->pc_cv, &pcp->pc_lock,
829
			    expires);
830
		}
831
		if (rval <= 0) {
832
			if (rval == 0)
833
				error = EINTR;
834
			break;
835
		}
836
	}
837
	mutex_exit(&pcp->pc_lock);
838

  
839
	if (pdp->pd_php != NULL) {
840
		pollhead_delete(pdp->pd_php, pdp);
841
		pdp->pd_php = NULL;
842
		pdp->pd_fd = NULL;
843
	}
844

  
845
	/*
846
	 * pollwakeup() may still interact with this pollcache. Wait until
847
	 * it is done.
848
	 */
849
	mutex_enter(&pcp->pc_no_exit);
850
	ASSERT(pcp->pc_busy >= 0);
851
	while (pcp->pc_busy > 0)
852
		cv_wait(&pcp->pc_busy_cv, &pcp->pc_no_exit);
853
	mutex_exit(&pcp->pc_no_exit);
854
out:
855
	pcache_destroy(pcp);
856
	return (error);
857
}
858

  
720 859
int
721 860
ksocket_sendmblk(ksocket_t ks, struct nmsghdr *msg, int flags,
722 861
    mblk_t **mpp, cred_t *cr)
usr/src/uts/common/sys/ksocket.h Thu Sep 22 13:37:45 2011 +0400 → usr/src/uts/common/sys/ksocket.h Fri Sep 30 16:31:38 2011 +0400
19 19
 * CDDL HEADER END
20 20
 */
21 21
/*
22
 * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
22 23
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 24
 */
24 25

  
......
113 114
extern int 	ksocket_getsockname(ksocket_t, struct sockaddr *, socklen_t *,
114 115
		    struct cred *);
115 116
extern int	ksocket_ioctl(ksocket_t, int, intptr_t, int *, struct cred *);
117
extern int	ksocket_spoll(ksocket_t, int, short, short *, struct cred *);
116 118
extern int	ksocket_setcallbacks(ksocket_t, ksocket_callbacks_t *, void *,
117 119
		    struct cred *);
118 120
extern int 	ksocket_close(ksocket_t, struct cred *);
(3-3/3)