poll-posix.cpp revision efdb1947ebed81cc00f8daf2c1040b2b2f5196db
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * IPRT - Polling I/O Handles, POSIX Implementation.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2010 Sun Microsystems, Inc.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * The contents of this file may alternatively be used under the terms
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * of the Common Development and Distribution License Version 1.0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution, in which case the provisions of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * CDDL are applicable instead of those of the GPL.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * You may elect to license modified versions of this file under the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * terms and conditions of either the GPL or the CDDL or both.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * additional information or have any questions.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Header Files *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Structures and Typedefs *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Handle entry in a poll set.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The handle type. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The handle ID. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The handle union. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Pointer to a handle entry. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Poll set data, POSIX.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The magic value (RTPOLLSET_MAGIC). */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Set when someone is polling or making changes. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync bool volatile fBusy;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The number of valid handles in the set. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The number of allocated handles. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Pointer to an array of pollfd structures. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Pointer to an array of handles and IDs. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Common worker for RTPoll and RTPollNoResume
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int rtPollNoResumeWorker(RTPOLLSETINTERNAL *pThis, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (RT_UNLIKELY(pThis->cHandles == 0 && cMillies == RT_INDEFINITE_WAIT))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* clear the revents. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (i-- > 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync int rc = poll(&pThis->paPollFds[0], pThis->cHandles,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cMillies == RT_INDEFINITE_WAIT || cMillies >= INT_MAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pThis->paPollFds[i].revents & (POLLERR | POLLHUP | POLLNVAL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTDECL(int) RTPoll(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Set the busy flag and do the job.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_WRONG_ORDER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync do rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTDECL(int) RTPollNoResume(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Set the busy flag and do the job.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_WRONG_ORDER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync int rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTPOLLSETINTERNAL *pThis = (RTPOLLSETINTERNAL *)RTMemAlloc(sizeof(RTPOLLSETINTERNAL));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_WRONG_ORDER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTDECL(int) RTPollSetAdd(RTPOLLSET hPollSet, PCRTHANDLE pHandle, uint32_t fEvents, uint32_t id)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Validate the input (tedious).
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(!(fEvents & ~RTPOLL_EVT_VALID_MASK), VERR_INVALID_PARAMETER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(id != UINT32_MAX, VERR_INVALID_PARAMETER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pHandle->enmType > RTHANDLETYPE_INVALID && pHandle->enmType < RTHANDLETYPE_END, VERR_INVALID_PARAMETER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Set the busy flag and do the job.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_WRONG_ORDER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fd = (int)pHandle->u.hSocket; //fd = RTTcpToNative(pHandle->u.hSocket);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgFailed(("Files are always ready for reading/writing and thus not pollable. Use native APIs for special devices.\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgFailed(("Thread handles are currently not pollable\n"));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Check that the handle ID doesn't exist already. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (j-- > 0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Grow the tables if necessary. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pvNew = RTMemRealloc(pThis->paHandles, c * sizeof(pThis->paHandles[0]));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pvNew = RTMemRealloc(pThis->paPollFds, c * sizeof(pThis->paPollFds[0]));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Add it to the poll file descriptor array and call poll to
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync validate the event flags. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Add the handle info and close the transaction. */
return rc;
if (cToMove)
return rc;
if (pHandle)
return rc;
return cHandles;