Changeset 77856 in vbox
- Timestamp:
- Mar 23, 2019 5:41:06 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r76553 r77856 33 33 #include <iprt/file.h> 34 34 #include <iprt/string.h> 35 #include <iprt/tcp.h>36 35 #include <iprt/semaphore.h> 37 36 #include <iprt/sg.h> 38 #include <iprt/poll.h>39 #include <iprt/pipe.h>40 37 #include <iprt/system.h> 41 38 #include <iprt/memsafer.h> … … 118 115 /** Configuration information interface. */ 119 116 VDINTERFACECONFIG VDIfConfig; 120 /** TCP network stack interface. */ 117 /** TCP network stack instance for host mode. */ 118 VDIFINST hVdIfTcpNet; 119 /** TCP network stack interface (for INIP). */ 121 120 VDINTERFACETCPNET VDIfTcpNet; 122 121 /** I/O interface. */ … … 486 485 PVBOXIMAGE p = pThis->pImages; 487 486 pThis->pImages = pThis->pImages->pNext; 487 if (p->hVdIfTcpNet != NULL) 488 VDIfTcpNetInstDefaultDestroy(p->hVdIfTcpNet); 488 489 RTMemFree(p); 489 490 } … … 1367 1368 #endif /* VBOX_WITH_INIP */ 1368 1369 1369 1370 /*********************************************************************************************************************************1371 * VD TCP network stack interface implementation - Host TCP case *1372 *********************************************************************************************************************************/1373 1374 /**1375 * Socket data.1376 */1377 typedef struct VDSOCKETINT1378 {1379 /** IPRT socket handle. */1380 RTSOCKET hSocket;1381 /** Pollset with the wakeup pipe and socket. */1382 RTPOLLSET hPollSet;1383 /** Pipe endpoint - read (in the pollset). */1384 RTPIPE hPipeR;1385 /** Pipe endpoint - write. */1386 RTPIPE hPipeW;1387 /** Flag whether the thread was woken up. */1388 volatile bool fWokenUp;1389 /** Flag whether the thread is waiting in the select call. */1390 volatile bool fWaiting;1391 /** Old event mask. */1392 uint32_t fEventsOld;1393 } VDSOCKETINT, *PVDSOCKETINT;1394 1395 /** Pollset id of the socket. */1396 #define VDSOCKET_POLL_ID_SOCKET 01397 /** Pollset id of the pipe. */1398 #define VDSOCKET_POLL_ID_PIPE 11399 1400 /** @interface_method_impl{VDINTERFACETCPNET,pfnSocketCreate} */1401 static DECLCALLBACK(int) drvvdTcpSocketCreate(uint32_t fFlags, PVDSOCKET phVdSock)1402 {1403 int rc = VINF_SUCCESS;1404 int rc2 = VINF_SUCCESS;1405 PVDSOCKETINT pSockInt = NULL;1406 1407 pSockInt = (PVDSOCKETINT)RTMemAllocZ(sizeof(VDSOCKETINT));1408 if (!pSockInt)1409 return VERR_NO_MEMORY;1410 1411 pSockInt->hSocket = NIL_RTSOCKET;1412 pSockInt->hPollSet = NIL_RTPOLLSET;1413 pSockInt->hPipeR = NIL_RTPIPE;1414 pSockInt->hPipeW = NIL_RTPIPE;1415 pSockInt->fWokenUp = false;1416 pSockInt->fWaiting = false;1417 1418 if (fFlags & VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT)1419 {1420 /* Init pipe and pollset. */1421 rc = RTPipeCreate(&pSockInt->hPipeR, &pSockInt->hPipeW, 0);1422 if (RT_SUCCESS(rc))1423 {1424 rc = RTPollSetCreate(&pSockInt->hPollSet);1425 if (RT_SUCCESS(rc))1426 {1427 rc = RTPollSetAddPipe(pSockInt->hPollSet, pSockInt->hPipeR,1428 RTPOLL_EVT_READ, VDSOCKET_POLL_ID_PIPE);1429 if (RT_SUCCESS(rc))1430 {1431 *phVdSock = pSockInt;1432 return VINF_SUCCESS;1433 }1434 1435 RTPollSetRemove(pSockInt->hPollSet, VDSOCKET_POLL_ID_PIPE);1436 rc2 = RTPollSetDestroy(pSockInt->hPollSet);1437 AssertRC(rc2);1438 }1439 1440 rc2 = RTPipeClose(pSockInt->hPipeR);1441 AssertRC(rc2);1442 rc2 = RTPipeClose(pSockInt->hPipeW);1443 AssertRC(rc2);1444 }1445 }1446 else1447 {1448 *phVdSock = pSockInt;1449 return VINF_SUCCESS;1450 }1451 1452 RTMemFree(pSockInt);1453 1454 return rc;1455 }1456 1457 /** @interface_method_impl{VDINTERFACETCPNET,pfnSocketDestroy} */1458 static DECLCALLBACK(int) drvvdTcpSocketDestroy(VDSOCKET hVdSock)1459 {1460 int rc = VINF_SUCCESS;1461 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1462 1463 /* Destroy the pipe and pollset if necessary. */1464 if (pSockInt->hPollSet != NIL_RTPOLLSET)1465 {1466 if (pSockInt->hSocket != NIL_RTSOCKET)1467 {1468 rc = RTPollSetRemove(pSockInt->hPollSet, VDSOCKET_POLL_ID_SOCKET);1469 Assert(RT_SUCCESS(rc) || rc == VERR_POLL_HANDLE_ID_NOT_FOUND);1470 }1471 rc = RTPollSetRemove(pSockInt->hPollSet, VDSOCKET_POLL_ID_PIPE);1472 AssertRC(rc);1473 rc = RTPollSetDestroy(pSockInt->hPollSet);1474 AssertRC(rc);1475 rc = RTPipeClose(pSockInt->hPipeR);1476 AssertRC(rc);1477 rc = RTPipeClose(pSockInt->hPipeW);1478 AssertRC(rc);1479 }1480 1481 if (pSockInt->hSocket != NIL_RTSOCKET)1482 rc = RTTcpClientCloseEx(pSockInt->hSocket, false /*fGracefulShutdown*/);1483 1484 RTMemFree(pSockInt);1485 1486 return rc;1487 }1488 1489 /** @interface_method_impl{VDINTERFACETCPNET,pfnClientConnect} */1490 static DECLCALLBACK(int) drvvdTcpClientConnect(VDSOCKET hVdSock, const char *pszAddress, uint32_t uPort,1491 RTMSINTERVAL cMillies)1492 {1493 int rc = VINF_SUCCESS;1494 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1495 1496 rc = RTTcpClientConnectEx(pszAddress, uPort, &pSockInt->hSocket, cMillies, NULL);1497 if (RT_SUCCESS(rc))1498 {1499 /* Add to the pollset if required. */1500 if (pSockInt->hPollSet != NIL_RTPOLLSET)1501 {1502 pSockInt->fEventsOld = RTPOLL_EVT_READ | RTPOLL_EVT_WRITE | RTPOLL_EVT_ERROR;1503 1504 rc = RTPollSetAddSocket(pSockInt->hPollSet, pSockInt->hSocket,1505 pSockInt->fEventsOld, VDSOCKET_POLL_ID_SOCKET);1506 }1507 1508 if (RT_SUCCESS(rc))1509 return VINF_SUCCESS;1510 1511 rc = RTTcpClientCloseEx(pSockInt->hSocket, false /*fGracefulShutdown*/);1512 }1513 1514 return rc;1515 }1516 1517 /** @interface_method_impl{VDINTERFACETCPNET,pfnClientClose} */1518 static DECLCALLBACK(int) drvvdTcpClientClose(VDSOCKET hVdSock)1519 {1520 int rc = VINF_SUCCESS;1521 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1522 1523 if (pSockInt->hPollSet != NIL_RTPOLLSET)1524 {1525 rc = RTPollSetRemove(pSockInt->hPollSet, VDSOCKET_POLL_ID_SOCKET);1526 AssertRC(rc);1527 }1528 1529 rc = RTTcpClientCloseEx(pSockInt->hSocket, false /*fGracefulShutdown*/);1530 pSockInt->hSocket = NIL_RTSOCKET;1531 1532 return rc;1533 }1534 1535 /** @interface_method_impl{VDINTERFACETCPNET,pfnIsClientConnected} */1536 static DECLCALLBACK(bool) drvvdTcpIsClientConnected(VDSOCKET hVdSock)1537 {1538 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1539 1540 return pSockInt->hSocket != NIL_RTSOCKET;1541 }1542 1543 /** @interface_method_impl{VDINTERFACETCPNET,pfnSelectOne} */1544 static DECLCALLBACK(int) drvvdTcpSelectOne(VDSOCKET hVdSock, RTMSINTERVAL cMillies)1545 {1546 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1547 1548 return RTTcpSelectOne(pSockInt->hSocket, cMillies);1549 }1550 1551 /** @interface_method_impl{VDINTERFACETCPNET,pfnRead} */1552 static DECLCALLBACK(int) drvvdTcpRead(VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)1553 {1554 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1555 1556 return RTTcpRead(pSockInt->hSocket, pvBuffer, cbBuffer, pcbRead);1557 }1558 1559 /** @interface_method_impl{VDINTERFACETCPNET,pfnWrite} */1560 static DECLCALLBACK(int) drvvdTcpWrite(VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer)1561 {1562 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1563 1564 return RTTcpWrite(pSockInt->hSocket, pvBuffer, cbBuffer);1565 }1566 1567 /** @interface_method_impl{VDINTERFACETCPNET,pfnSgWrite} */1568 static DECLCALLBACK(int) drvvdTcpSgWrite(VDSOCKET hVdSock, PCRTSGBUF pSgBuf)1569 {1570 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1571 1572 return RTTcpSgWrite(pSockInt->hSocket, pSgBuf);1573 }1574 1575 /** @interface_method_impl{VDINTERFACETCPNET,pfnReadNB} */1576 static DECLCALLBACK(int) drvvdTcpReadNB(VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)1577 {1578 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1579 1580 return RTTcpReadNB(pSockInt->hSocket, pvBuffer, cbBuffer, pcbRead);1581 }1582 1583 /** @interface_method_impl{VDINTERFACETCPNET,pfnWriteNB} */1584 static DECLCALLBACK(int) drvvdTcpWriteNB(VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)1585 {1586 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1587 1588 return RTTcpWriteNB(pSockInt->hSocket, pvBuffer, cbBuffer, pcbWritten);1589 }1590 1591 /** @interface_method_impl{VDINTERFACETCPNET,pfnSgWriteNB} */1592 static DECLCALLBACK(int) drvvdTcpSgWriteNB(VDSOCKET hVdSock, PRTSGBUF pSgBuf, size_t *pcbWritten)1593 {1594 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1595 1596 return RTTcpSgWriteNB(pSockInt->hSocket, pSgBuf, pcbWritten);1597 }1598 1599 /** @interface_method_impl{VDINTERFACETCPNET,pfnFlush} */1600 static DECLCALLBACK(int) drvvdTcpFlush(VDSOCKET hVdSock)1601 {1602 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1603 1604 return RTTcpFlush(pSockInt->hSocket);1605 }1606 1607 /** @interface_method_impl{VDINTERFACETCPNET,pfnSetSendCoalescing} */1608 static DECLCALLBACK(int) drvvdTcpSetSendCoalescing(VDSOCKET hVdSock, bool fEnable)1609 {1610 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1611 1612 return RTTcpSetSendCoalescing(pSockInt->hSocket, fEnable);1613 }1614 1615 /** @interface_method_impl{VDINTERFACETCPNET,pfnGetLocalAddress} */1616 static DECLCALLBACK(int) drvvdTcpGetLocalAddress(VDSOCKET hVdSock, PRTNETADDR pAddr)1617 {1618 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1619 1620 return RTTcpGetLocalAddress(pSockInt->hSocket, pAddr);1621 }1622 1623 /** @interface_method_impl{VDINTERFACETCPNET,pfnGetPeerAddress} */1624 static DECLCALLBACK(int) drvvdTcpGetPeerAddress(VDSOCKET hVdSock, PRTNETADDR pAddr)1625 {1626 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1627 1628 return RTTcpGetPeerAddress(pSockInt->hSocket, pAddr);1629 }1630 1631 static DECLCALLBACK(int) drvvdTcpSelectOneExPoll(VDSOCKET hVdSock, uint32_t fEvents,1632 uint32_t *pfEvents, RTMSINTERVAL cMillies)1633 {1634 int rc = VINF_SUCCESS;1635 uint32_t id = 0;1636 uint32_t fEventsRecv = 0;1637 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1638 1639 *pfEvents = 0;1640 1641 if ( pSockInt->fEventsOld != fEvents1642 && pSockInt->hSocket != NIL_RTSOCKET)1643 {1644 uint32_t fPollEvents = 0;1645 1646 if (fEvents & VD_INTERFACETCPNET_EVT_READ)1647 fPollEvents |= RTPOLL_EVT_READ;1648 if (fEvents & VD_INTERFACETCPNET_EVT_WRITE)1649 fPollEvents |= RTPOLL_EVT_WRITE;1650 if (fEvents & VD_INTERFACETCPNET_EVT_ERROR)1651 fPollEvents |= RTPOLL_EVT_ERROR;1652 1653 rc = RTPollSetEventsChange(pSockInt->hPollSet, VDSOCKET_POLL_ID_SOCKET, fPollEvents);1654 if (RT_FAILURE(rc))1655 return rc;1656 1657 pSockInt->fEventsOld = fEvents;1658 }1659 1660 ASMAtomicXchgBool(&pSockInt->fWaiting, true);1661 if (ASMAtomicXchgBool(&pSockInt->fWokenUp, false))1662 {1663 ASMAtomicXchgBool(&pSockInt->fWaiting, false);1664 return VERR_INTERRUPTED;1665 }1666 1667 rc = RTPoll(pSockInt->hPollSet, cMillies, &fEventsRecv, &id);1668 Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);1669 1670 ASMAtomicXchgBool(&pSockInt->fWaiting, false);1671 1672 if (RT_SUCCESS(rc))1673 {1674 if (id == VDSOCKET_POLL_ID_SOCKET)1675 {1676 fEventsRecv &= RTPOLL_EVT_VALID_MASK;1677 1678 if (fEventsRecv & RTPOLL_EVT_READ)1679 *pfEvents |= VD_INTERFACETCPNET_EVT_READ;1680 if (fEventsRecv & RTPOLL_EVT_WRITE)1681 *pfEvents |= VD_INTERFACETCPNET_EVT_WRITE;1682 if (fEventsRecv & RTPOLL_EVT_ERROR)1683 *pfEvents |= VD_INTERFACETCPNET_EVT_ERROR;1684 }1685 else1686 {1687 size_t cbRead = 0;1688 uint8_t abBuf[10];1689 Assert(id == VDSOCKET_POLL_ID_PIPE);1690 Assert((fEventsRecv & RTPOLL_EVT_VALID_MASK) == RTPOLL_EVT_READ);1691 1692 /* We got interrupted, drain the pipe. */1693 rc = RTPipeRead(pSockInt->hPipeR, abBuf, sizeof(abBuf), &cbRead);1694 AssertRC(rc);1695 1696 ASMAtomicXchgBool(&pSockInt->fWokenUp, false);1697 1698 rc = VERR_INTERRUPTED;1699 }1700 }1701 1702 return rc;1703 }1704 1705 /** @interface_method_impl{VDINTERFACETCPNET,pfnSelectOneEx} */1706 static DECLCALLBACK(int) drvvdTcpSelectOneExNoPoll(VDSOCKET hVdSock, uint32_t fEvents, uint32_t *pfEvents, RTMSINTERVAL cMillies)1707 {1708 RT_NOREF(cMillies); /** @todo timeouts */1709 int rc = VINF_SUCCESS;1710 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1711 1712 *pfEvents = 0;1713 1714 ASMAtomicXchgBool(&pSockInt->fWaiting, true);1715 if (ASMAtomicXchgBool(&pSockInt->fWokenUp, false))1716 {1717 ASMAtomicXchgBool(&pSockInt->fWaiting, false);1718 return VERR_INTERRUPTED;1719 }1720 1721 if ( pSockInt->hSocket == NIL_RTSOCKET1722 || !fEvents)1723 {1724 /*1725 * Only the pipe is configured or the caller doesn't wait for a socket event,1726 * wait until there is something to read from the pipe.1727 */1728 size_t cbRead = 0;1729 char ch = 0;1730 rc = RTPipeReadBlocking(pSockInt->hPipeR, &ch, 1, &cbRead);1731 if (RT_SUCCESS(rc))1732 {1733 Assert(cbRead == 1);1734 rc = VERR_INTERRUPTED;1735 ASMAtomicXchgBool(&pSockInt->fWokenUp, false);1736 }1737 }1738 else1739 {1740 uint32_t fSelectEvents = 0;1741 1742 if (fEvents & VD_INTERFACETCPNET_EVT_READ)1743 fSelectEvents |= RTSOCKET_EVT_READ;1744 if (fEvents & VD_INTERFACETCPNET_EVT_WRITE)1745 fSelectEvents |= RTSOCKET_EVT_WRITE;1746 if (fEvents & VD_INTERFACETCPNET_EVT_ERROR)1747 fSelectEvents |= RTSOCKET_EVT_ERROR;1748 1749 if (fEvents & VD_INTERFACETCPNET_HINT_INTERRUPT)1750 {1751 uint32_t fEventsRecv = 0;1752 1753 /* Make sure the socket is not in the pollset. */1754 rc = RTPollSetRemove(pSockInt->hPollSet, VDSOCKET_POLL_ID_SOCKET);1755 Assert(RT_SUCCESS(rc) || rc == VERR_POLL_HANDLE_ID_NOT_FOUND);1756 1757 for (;;)1758 {1759 uint32_t id = 0;1760 rc = RTPoll(pSockInt->hPollSet, 5, &fEvents, &id);1761 if (rc == VERR_TIMEOUT)1762 {1763 /* Check the socket. */1764 rc = RTTcpSelectOneEx(pSockInt->hSocket, fSelectEvents, &fEventsRecv, 0);1765 if (RT_SUCCESS(rc))1766 {1767 if (fEventsRecv & RTSOCKET_EVT_READ)1768 *pfEvents |= VD_INTERFACETCPNET_EVT_READ;1769 if (fEventsRecv & RTSOCKET_EVT_WRITE)1770 *pfEvents |= VD_INTERFACETCPNET_EVT_WRITE;1771 if (fEventsRecv & RTSOCKET_EVT_ERROR)1772 *pfEvents |= VD_INTERFACETCPNET_EVT_ERROR;1773 break; /* Quit */1774 }1775 else if (rc != VERR_TIMEOUT)1776 break;1777 }1778 else if (RT_SUCCESS(rc))1779 {1780 size_t cbRead = 0;1781 uint8_t abBuf[10];1782 Assert(id == VDSOCKET_POLL_ID_PIPE);1783 Assert((fEventsRecv & RTPOLL_EVT_VALID_MASK) == RTPOLL_EVT_READ);1784 1785 /* We got interrupted, drain the pipe. */1786 rc = RTPipeRead(pSockInt->hPipeR, abBuf, sizeof(abBuf), &cbRead);1787 AssertRC(rc);1788 1789 ASMAtomicXchgBool(&pSockInt->fWokenUp, false);1790 1791 rc = VERR_INTERRUPTED;1792 break;1793 }1794 else1795 break;1796 }1797 }1798 else /* The caller waits for a socket event. */1799 {1800 uint32_t fEventsRecv = 0;1801 1802 /* Loop until we got woken up or a socket event occurred. */1803 for (;;)1804 {1805 /** @todo find an adaptive wait algorithm based on the1806 * number of wakeups in the past. */1807 rc = RTTcpSelectOneEx(pSockInt->hSocket, fSelectEvents, &fEventsRecv, 5);1808 if (rc == VERR_TIMEOUT)1809 {1810 /* Check if there is an event pending. */1811 size_t cbRead = 0;1812 char ch = 0;1813 rc = RTPipeRead(pSockInt->hPipeR, &ch, 1, &cbRead);1814 if (RT_SUCCESS(rc) && rc != VINF_TRY_AGAIN)1815 {1816 Assert(cbRead == 1);1817 rc = VERR_INTERRUPTED;1818 ASMAtomicXchgBool(&pSockInt->fWokenUp, false);1819 break; /* Quit */1820 }1821 else1822 Assert(rc == VINF_TRY_AGAIN);1823 }1824 else if (RT_SUCCESS(rc))1825 {1826 if (fEventsRecv & RTSOCKET_EVT_READ)1827 *pfEvents |= VD_INTERFACETCPNET_EVT_READ;1828 if (fEventsRecv & RTSOCKET_EVT_WRITE)1829 *pfEvents |= VD_INTERFACETCPNET_EVT_WRITE;1830 if (fEventsRecv & RTSOCKET_EVT_ERROR)1831 *pfEvents |= VD_INTERFACETCPNET_EVT_ERROR;1832 break; /* Quit */1833 }1834 else1835 break;1836 }1837 }1838 }1839 1840 ASMAtomicXchgBool(&pSockInt->fWaiting, false);1841 1842 return rc;1843 }1844 1845 /** @interface_method_impl{VDINTERFACETCPNET,pfnPoke} */1846 static DECLCALLBACK(int) drvvdTcpPoke(VDSOCKET hVdSock)1847 {1848 int rc = VINF_SUCCESS;1849 size_t cbWritten = 0;1850 PVDSOCKETINT pSockInt = (PVDSOCKETINT)hVdSock;1851 1852 ASMAtomicXchgBool(&pSockInt->fWokenUp, true);1853 1854 if (ASMAtomicReadBool(&pSockInt->fWaiting))1855 {1856 rc = RTPipeWrite(pSockInt->hPipeW, "", 1, &cbWritten);1857 Assert(RT_SUCCESS(rc) || cbWritten == 0);1858 }1859 1860 return VINF_SUCCESS;1861 }1862 1370 1863 1371 /** … … 5595 5103 * done unconditionally, as uninterested backends will ignore it. */ 5596 5104 if (fHostIP) 5597 { 5598 pImage->VDIfTcpNet.pfnSocketCreate = drvvdTcpSocketCreate; 5599 pImage->VDIfTcpNet.pfnSocketDestroy = drvvdTcpSocketDestroy; 5600 pImage->VDIfTcpNet.pfnClientConnect = drvvdTcpClientConnect; 5601 pImage->VDIfTcpNet.pfnIsClientConnected = drvvdTcpIsClientConnected; 5602 pImage->VDIfTcpNet.pfnClientClose = drvvdTcpClientClose; 5603 pImage->VDIfTcpNet.pfnSelectOne = drvvdTcpSelectOne; 5604 pImage->VDIfTcpNet.pfnRead = drvvdTcpRead; 5605 pImage->VDIfTcpNet.pfnWrite = drvvdTcpWrite; 5606 pImage->VDIfTcpNet.pfnSgWrite = drvvdTcpSgWrite; 5607 pImage->VDIfTcpNet.pfnReadNB = drvvdTcpReadNB; 5608 pImage->VDIfTcpNet.pfnWriteNB = drvvdTcpWriteNB; 5609 pImage->VDIfTcpNet.pfnSgWriteNB = drvvdTcpSgWriteNB; 5610 pImage->VDIfTcpNet.pfnFlush = drvvdTcpFlush; 5611 pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdTcpSetSendCoalescing; 5612 pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdTcpGetLocalAddress; 5613 pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdTcpGetPeerAddress; 5614 5615 /* 5616 * There is a 15ms delay between receiving the data and marking the socket 5617 * as readable on Windows XP which hurts async I/O performance of 5618 * TCP backends badly. Provide a different select method without 5619 * using poll on XP. 5620 * This is only used on XP because it is not as efficient as the one using poll 5621 * and all other Windows versions are working fine. 5622 */ 5623 char szOS[64]; 5624 memset(szOS, 0, sizeof(szOS)); 5625 rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, &szOS[0], sizeof(szOS)); 5626 5627 if (RT_SUCCESS(rc) && !strncmp(szOS, "Windows XP", 10)) 5628 { 5629 LogRel(("VD: Detected Windows XP, disabled poll based waiting for TCP\n")); 5630 pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExNoPoll; 5631 } 5632 else 5633 pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExPoll; 5634 5635 pImage->VDIfTcpNet.pfnPoke = drvvdTcpPoke; 5636 } 5105 rc = VDIfTcpNetInstDefaultCreate(&pImage->hVdIfTcpNet, &pImage->pVDIfsImage); 5637 5106 else 5638 5107 { … … 5656 5125 pImage->VDIfTcpNet.pfnSelectOneEx = drvvdINIPSelectOneEx; 5657 5126 pImage->VDIfTcpNet.pfnPoke = drvvdINIPPoke; 5127 5128 rc = VDInterfaceAdd(&pImage->VDIfTcpNet.Core, "DrvVD_TCPNET", 5129 VDINTERFACETYPE_TCPNET, NULL, 5130 sizeof(VDINTERFACETCPNET), &pImage->pVDIfsImage); 5131 AssertRC(rc); 5658 5132 #endif /* VBOX_WITH_INIP */ 5659 5133 } 5660 rc = VDInterfaceAdd(&pImage->VDIfTcpNet.Core, "DrvVD_TCPNET",5661 VDINTERFACETYPE_TCPNET, NULL,5662 sizeof(VDINTERFACETCPNET), &pImage->pVDIfsImage);5663 AssertRC(rc);5664 5134 5665 5135 /* Insert the custom I/O interface only if we're told to use new IO. -
trunk/src/VBox/Devices/build/VBoxDDUDeps.cpp
r76553 r77856 40 40 (PFNRT)VDIfCreateFromVfsStream, 41 41 (PFNRT)VDCreateVfsFileFromDisk, 42 (PFNRT)VDIfTcpNetInstDefaultCreate, 42 43 #ifdef VBOX_WITH_USB 43 44 (PFNRT)USBFilterInit,
Note:
See TracChangeset
for help on using the changeset viewer.