VirtualBox

Changeset 30468 in vbox


Ignore:
Timestamp:
Jun 28, 2010 1:58:04 PM (15 years ago)
Author:
vboxsync
Message:

IPRT:

  • Corrected RTSGBUF member names.
  • Corrected RTSgBufInit parameter names.
  • Don't use AssertReturnVoid (and variations) in RTSgBuf* as there the result is that we use uninitialized structures. Better to crash and burn in IPRT then.
  • Added RTSocketSgWriteL/LV and RTTcpSgWriteL/LV for lazy guys like me.
  • RTSocketSgWrite doesn't need a do {} while (0).
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/sg.h

    r28800 r30468  
    5656{
    5757    /** Pointer to the scatter/gather array. */
    58     PCRTSGSEG pcaSeg;
     58    PCRTSGSEG paSegs;
    5959    /** Number of segments. */
    60     unsigned  cSeg;
     60    unsigned  cSegs;
    6161    /** Current segment we are in. */
    6262    unsigned  idxSeg;
    6363    /** Pointer to the current segment start. */
    64     void     *pvSegCurr;
     64    void     *pvSegCur;
    6565    /** Number of bytes left in the current buffer. */
    6666    size_t    cbSegLeft;
     
    7878 * @returns nothing.
    7979 * @param   pSgBuf    Pointer to the S/G buffer to initialize.
    80  * @param   pcaSeg    Pointer to the start of the segment array.
    81  * @param   cSeg      Number of segments in the array.
    82  */
    83 RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG pcaSeg, unsigned cSeg);
     80 * @param   paSegs    Pointer to the start of the segment array.
     81 * @param   cSegs     Number of segments in the array.
     82 */
     83RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, unsigned cSegs);
    8484
    8585/**
  • trunk/include/iprt/socket.h

    r30270 r30468  
    188188RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf);
    189189
     190/**
     191 * Send data from multiple buffers to a socket.
     192 *
     193 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
     194 * for lazy coders.  The "L" in the function name is short for "list" just like
     195 * in the execl libc API.
     196 *
     197 * @returns IPRT status code.
     198 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
     199 *
     200 * @param   hSocket         The socket handle.
     201 * @param   cSegs           The number of data segments in the following
     202 *                          ellipsis.
     203 * @param   ...             Pairs of buffer pointers (void const *) and buffer
     204 *                          sizes (size_t).  Make 101% sure the pointer is
     205 *                          really size_t.
     206 */
     207RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...);
     208
     209/**
     210 * Send data from multiple buffers to a socket.
     211 *
     212 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
     213 * for lazy coders.  The "L" in the function name is short for "list" just like
     214 * in the execl libc API.
     215 *
     216 * @returns IPRT status code.
     217 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
     218 *
     219 * @param   hSocket         The socket handle.
     220 * @param   cSegs           The number of data segments in the following
     221 *                          argument list.
     222 * @param   va              Pairs of buffer pointers (void const *) and buffer
     223 *                          sizes (size_t).  Make 101% sure the pointer is
     224 *                          really size_t.
     225 */
     226RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va);
     227
    190228/** @} */
    191229RT_C_DECLS_END
  • trunk/include/iprt/tcp.h

    r30270 r30468  
    292292RTR3DECL(int)  RTTcpSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf);
    293293
     294
     295/**
     296 * Send data from multiple buffers to a socket.
     297 *
     298 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
     299 * for lazy coders.  The "L" in the function name is short for "list" just like
     300 * in the execl libc API.
     301 *
     302 * @returns IPRT status code.
     303 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
     304 *
     305 * @param   hSocket         The socket handle.
     306 * @param   cSegs           The number of data segments in the following
     307 *                          ellipsis.
     308 * @param   ...             Pairs of buffer pointers (void const *) and buffer
     309 *                          sizes (size_t).  Make 101% sure the pointer is
     310 *                          really size_t.
     311 */
     312RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...);
     313
     314/**
     315 * Send data from multiple buffers to a socket.
     316 *
     317 * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
     318 * for lazy coders.  The "L" in the function name is short for "list" just like
     319 * in the execl libc API.
     320 *
     321 * @returns IPRT status code.
     322 * @retval  VERR_INTERRUPTED if interrupted before anything was written.
     323 *
     324 * @param   hSocket         The socket handle.
     325 * @param   cSegs           The number of data segments in the following
     326 *                          argument list.
     327 * @param   va              Pairs of buffer pointers (void const *) and buffer
     328 *                          sizes (size_t). Make 101% sure the pointer is
     329 *                          really size_t.
     330 */
     331RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va);
     332
    294333/** @} */
    295334RT_C_DECLS_END
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r30309 r30468  
    740740    /* This is an extremely crude emulation, however it's good enough
    741741     * for our iSCSI code. INIP has no sendmsg(). */
    742     for (unsigned i = 0; i < pSgBuf->cSeg; i++)
    743     {
    744         rc = drvvdINIPWrite(Sock, pSgBuf->pcaSeg[i].pvSeg,
    745                             pSgBuf->pcaSeg[i].cbSeg);
     742    for (unsigned i = 0; i < pSgBuf->cSegs; i++)
     743    {
     744        rc = drvvdINIPWrite(Sock, pSgBuf->paSegs[i].pvSeg,
     745                            pSgBuf->paSegs[i].cbSeg);
    746746        if (RT_FAILURE(rc))
    747747            break;
  • trunk/src/VBox/Runtime/common/misc/sg.cpp

    r28800 r30468  
    3737{
    3838    size_t cbData = RT_MIN(*pcbData, pSgBuf->cbSegLeft);
    39     void *pvBuf = pSgBuf->pvSegCurr;
     39    void *pvBuf = pSgBuf->pvSegCur;
    4040
    4141    pSgBuf->cbSegLeft -= cbData;
     
    4646        pSgBuf->idxSeg++;
    4747
    48         if (RT_UNLIKELY(pSgBuf->idxSeg == pSgBuf->cSeg))
     48        if (RT_UNLIKELY(pSgBuf->idxSeg == pSgBuf->cSegs))
    4949        {
    5050            pSgBuf->cbSegLeft = 0;
    51             pSgBuf->pvSegCurr = NULL;
     51            pSgBuf->pvSegCur  = NULL;
    5252        }
    5353        else
    5454        {
    55             pSgBuf->pvSegCurr = pSgBuf->pcaSeg[pSgBuf->idxSeg].pvSeg;
    56             pSgBuf->cbSegLeft = pSgBuf->pcaSeg[pSgBuf->idxSeg].cbSeg;
     55            pSgBuf->pvSegCur  = pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg;
     56            pSgBuf->cbSegLeft = pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg;
    5757        }
    5858
     
    6060    }
    6161    else
    62         pSgBuf->pvSegCurr = (void *)((uintptr_t)pSgBuf->pvSegCurr + cbData);
     62        pSgBuf->pvSegCur = (uint8_t *)pSgBuf->pvSegCur + cbData;
    6363
    6464    return pvBuf;
     
    6666
    6767
    68 RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG pcaSeg, unsigned cSeg)
     68RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, unsigned cSegs)
     69{
     70    AssertPtr(pSgBuf);
     71    AssertPtr(paSegs);
     72    Assert(cSegs > 0);
     73
     74    pSgBuf->paSegs    = paSegs;
     75    pSgBuf->cSegs     = cSegs;
     76    pSgBuf->idxSeg    = 0;
     77    pSgBuf->pvSegCur  = paSegs[0].pvSeg;
     78    pSgBuf->cbSegLeft = paSegs[0].cbSeg;
     79}
     80
     81
     82RTDECL(void) RTSgBufReset(PRTSGBUF pSgBuf)
    6983{
    7084    AssertPtrReturnVoid(pSgBuf);
    71     AssertPtrReturnVoid(pcaSeg);
    72     AssertReturnVoid(cSeg > 0);
    73 
    74     pSgBuf->pcaSeg    = pcaSeg;
    75     pSgBuf->cSeg      = cSeg;
     85
    7686    pSgBuf->idxSeg    = 0;
    77     pSgBuf->pvSegCurr = pcaSeg[0].pvSeg;
    78     pSgBuf->cbSegLeft = pcaSeg[0].cbSeg;
    79 }
    80 
    81 
    82 RTDECL(void) RTSgBufReset(PRTSGBUF pSgBuf)
    83 {
    84     AssertPtrReturnVoid(pSgBuf);
    85 
    86     pSgBuf->idxSeg    = 0;
    87     pSgBuf->pvSegCurr = pSgBuf->pcaSeg[0].pvSeg;
    88     pSgBuf->cbSegLeft = pSgBuf->pcaSeg[0].cbSeg;
     87    pSgBuf->pvSegCur  = pSgBuf->paSegs[0].pvSeg;
     88    pSgBuf->cbSegLeft = pSgBuf->paSegs[0].cbSeg;
    8989}
    9090
     
    9292RTDECL(void) RTSgBufClone(PRTSGBUF pSgBufTo, PCRTSGBUF pSgBufFrom)
    9393{
    94     AssertPtrReturnVoid(pSgBufTo);
    95     AssertPtrReturnVoid(pSgBufFrom);
    96 
    97     pSgBufTo->pcaSeg    = pSgBufFrom->pcaSeg;
    98     pSgBufTo->cSeg      = pSgBufFrom->cSeg;
     94    AssertPtr(pSgBufTo);
     95    AssertPtr(pSgBufFrom);
     96
     97    pSgBufTo->paSegs    = pSgBufFrom->paSegs;
     98    pSgBufTo->cSegs     = pSgBufFrom->cSegs;
    9999    pSgBufTo->idxSeg    = pSgBufFrom->idxSeg;
    100     pSgBufTo->pvSegCurr = pSgBufFrom->pvSegCurr;
     100    pSgBufTo->pvSegCur  = pSgBufFrom->pvSegCur;
    101101    pSgBufTo->cbSegLeft = pSgBufFrom->cbSegLeft;
    102102}
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r30307 r30468  
    5252#include <iprt/socket.h>
    5353
     54#include <iprt/alloca.h>
    5455#include <iprt/asm.h>
    5556#include <iprt/assert.h>
     
    586587    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE);
    587588    AssertPtrReturn(pSgBuf, VERR_INVALID_PARAMETER);
    588     AssertReturn(pSgBuf->cSeg > 0, VERR_INVALID_PARAMETER);
     589    AssertReturn(pSgBuf->cSegs > 0, VERR_INVALID_PARAMETER);
    589590    AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
    590591
     
    592593     * Construct message descriptor (translate pSgBuf) and send it.
    593594     */
    594     int rc = VINF_SUCCESS;
    595     do
    596     {
    597 #ifdef RT_OS_WINDOWS
    598         AssertCompileSize(WSABUF, sizeof(RTSGSEG));
    599         AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
    600 
    601         LPWSABUF paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(WSABUF));
    602         AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY);
    603         for (unsigned i = 0; i < pSgBuf->cSeg; i++)
     595    int rc = VERR_NO_TMP_MEMORY;
     596#ifdef RT_OS_WINDOWS
     597    AssertCompileSize(WSABUF, sizeof(RTSGSEG));
     598    AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
     599
     600    LPWSABUF paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(WSABUF));
     601    if (paMsg)
     602    {
     603        for (unsigned i = 0; i < pSgBuf->cSegs; i++)
    604604        {
    605             paMsg[i].buf = (char *)pSgBuf->pcaSeg[i].pvSeg;
    606             paMsg[i].len = (u_long)pSgBuf->pcaSeg[i].cbSeg;
     605            paMsg[i].buf = (char *)pSgBuf->paSegs[i].pvSeg;
     606            paMsg[i].len = (u_long)pSgBuf->paSegs[i].cbSeg;
    607607        }
    608608
    609609        DWORD dwSent;
    610         int hrc = WSASend(pThis->hNative, paMsg, pSgBuf->cSeg, &dwSent,
     610        int hrc = WSASend(pThis->hNative, paMsg, pSgBuf->cSegs, &dwSent,
    611611                          MSG_NOSIGNAL, NULL, NULL);
    612         ssize_t cbWritten;
    613612        if (!hrc)
     613            rc = VINF_SUCCESS;
     614/** @todo check for incomplete writes */
     615        else
     616            rc = rtSocketError();
     617
     618        RTMemTmpFree(paMsg);
     619    }
     620
     621#else  /* !RT_OS_WINDOWS */
     622    AssertCompileSize(struct iovec, sizeof(RTSGSEG));
     623    AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
     624    AssertCompileMemberSize(struct iovec, iov_len,  RT_SIZEOFMEMB(RTSGSEG, cbSeg));
     625
     626    struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(struct iovec));
     627    if (paMsg)
     628    {
     629        for (unsigned i = 0; i < pSgBuf->cSegs; i++)
    614630        {
    615             /* avoid overflowing ssize_t, the exact value isn't important */
    616             cbWritten = RT_MIN(dwSent, INT_MAX);
     631            paMsg[i].iov_base = pSgBuf->paSegs[i].pvSeg;
     632            paMsg[i].iov_len  = pSgBuf->paSegs[i].cbSeg;
    617633        }
    618         else
    619             cbWritten = -1;
    620 #else
    621         AssertCompileSize(struct iovec, sizeof(RTSGSEG));
    622         AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg));
    623         AssertCompileMemberSize(struct iovec, iov_len, RT_SIZEOFMEMB(RTSGSEG, cbSeg));
    624 
    625         struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(struct iovec));
    626         AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY);
    627         for (unsigned i = 0; i < pSgBuf->cSeg; i++)
    628         {
    629             paMsg[i].iov_base = pSgBuf->pcaSeg[i].pvSeg;
    630             paMsg[i].iov_len = pSgBuf->pcaSeg[i].cbSeg;
    631         }
    632634
    633635        struct msghdr msgHdr;
    634         memset(&msgHdr, '\0', sizeof(msgHdr));
    635         msgHdr.msg_iov = paMsg;
    636         msgHdr.msg_iovlen = pSgBuf->cSeg;
     636        RT_ZERO(msgHdr);
     637        msgHdr.msg_iov    = paMsg;
     638        msgHdr.msg_iovlen = pSgBuf->cSegs;
    637639        ssize_t cbWritten = sendmsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL);
    638 #endif
    639 
    640         RTMemTmpFree(paMsg);
    641640        if (RT_LIKELY(cbWritten >= 0))
    642641            rc = VINF_SUCCESS;
     642/** @todo check for incomplete writes */
    643643        else
    644644            rc = rtSocketError();
    645     } while (0);
     645
     646        RTMemTmpFree(paMsg);
     647    }
     648#endif /* !RT_OS_WINDOWS */
    646649
    647650    rtSocketUnlock(pThis);
    648651    return rc;
     652}
     653
     654
     655RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...)
     656{
     657    va_list va;
     658    va_start(va, cSegs);
     659    int rc = RTSocketSgWriteLV(hSocket, cSegs, va);
     660    va_end(va);
     661    return rc;
     662}
     663
     664
     665RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va)
     666{
     667    /*
     668     * Set up a S/G segment array + buffer on the stack and pass it
     669     * on to RTSocketSgWrite.
     670     */
     671    Assert(cSegs <= 16);
     672    PRTSGSEG paSegs = (PRTSGSEG)alloca(cSegs * sizeof(RTSGSEG));
     673    AssertReturn(paSegs, VERR_NO_TMP_MEMORY);
     674    for (size_t i = 0; i < cSegs; i++)
     675    {
     676        paSegs[i].pvSeg = va_arg(va, void *);
     677        paSegs[i].cbSeg = va_arg(va, size_t);
     678    }
     679
     680    RTSGBUF SgBuf;
     681    RTSgBufInit(&SgBuf, paSegs, cSegs);
     682    return RTSocketSgWrite(hSocket, &SgBuf);
    649683}
    650684
  • trunk/src/VBox/Runtime/r3/tcp.cpp

    r30270 r30468  
    10201020}
    10211021
     1022
     1023RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...)
     1024{
     1025    va_list va;
     1026    va_start(va, cSegs);
     1027    int rc = RTSocketSgWriteLV(hSocket, cSegs, va);
     1028    va_end(va);
     1029    return rc;
     1030}
     1031
     1032
     1033RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va)
     1034{
     1035    return RTSocketSgWriteLV(hSocket, cSegs, va);
     1036}
     1037
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette