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)
|