VirtualBox

Changeset 48092 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 27, 2013 4:35:28 PM (11 years ago)
Author:
vboxsync
Message:

Drop "fini" callback/arg from tcpip_init() to minimize diffs from
upstream. It's redundant as well. Init callback is necessary because
you want to execute it at the very beginning of tcpip_thread() before
any messages are processed, so normal mbox messages are not suitable
for this.

Instead make termination message (already introduced for VBOX) act as
a callback and use it to pass our fini callback. Rename its message
type to more mnemonic TCPIP_MSG_CALLBACK_TERMINATE.

While here, rototill VBoxLwipCore.cpp to use locking properly and get
rid of global storage for LWIPCOREUSERCALLBACK - since we are waiting
for init/fini callback completion, we can use local variables.

I think VBoxLwipCore.cpp is a bit misguided, since I'm pretty sure
that, for example, you cannot shutdown and then re-init lwip in its
current shape, but for now jsut simplify it as far as we can.

Location:
trunk/src/VBox/Devices/Network
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/VBoxLwipCore.cpp

    r48048 r48092  
    3030/* @todo: lwip or nat ? */
    3131#define LOG_GROUP LOG_GROUP_DRV_NAT
    32 #include <iprt/critsect.h>
     32#include <iprt/cpp/lock.h>
    3333#include <iprt/timer.h>
    3434#include <VBox/err.h>
     
    5252
    5353
     54RTCLockMtx g_mtxLwip;
     55
    5456typedef struct LWIPCORE
    5557{
    5658    int iLWIPInitiatorCounter;
    57     /* semaphore to coordinate 'tcpip' thread initialization */
    5859    sys_sem_t LwipTcpIpSem;
    59     /* Initalization user defined callback */
    60     LWIPCOREUSERCALLBACK userInitClbk;
    61     /* Finitialization user defined callback */
    62     LWIPCOREUSERCALLBACK userFiniClbk;
    63     RTCRITSECT csLwipCore;
    6460} LWIPCORE;
    6561
     
    6864
    6965/**
    70  * @note: this function executed on TCPIP thread.
     66 * @note: this function executes on TCPIP thread.
     67 */
     68static DECLCALLBACK(void) lwipCoreUserCallback(void *pvArg)
     69{
     70    LogFlowFunc(("ENTER: pvArg:%p\n", pvArg));
     71
     72    PLWIPCOREUSERCALLBACK pUserClbk = (PLWIPCOREUSERCALLBACK)pvArg;
     73    if (pUserClbk != NULL && pUserClbk->pfn != NULL)
     74        pUserClbk->pfn(pUserClbk->pvUser);
     75
     76    /* wake up caller on EMT/main */
     77    lwip_sys_sem_signal(&g_LwipCore.LwipTcpIpSem);
     78    LogFlowFuncLeave();
     79}
     80
     81
     82/**
     83 * @note: this function executes on TCPIP thread.
    7184 */
    7285static DECLCALLBACK(void) lwipCoreInitDone(void *pvArg)
    7386{
    74     sys_sem_t *pLwipSem = (sys_sem_t *)pvArg;
    7587    LogFlowFunc(("ENTER: pvArg:%p\n", pvArg));
    76     AssertPtrReturnVoid(pvArg);
    77     lwip_sys_sem_signal(pLwipSem);
    78     LogFlowFuncLeave();
    79 }
    80 
    81 /**
    82  * @note: this function executed on TCPIP thread.
     88
     89    /* ... init code goes here if need be ... */
     90
     91    lwipCoreUserCallback(pvArg);
     92    LogFlowFuncLeave();
     93}
     94
     95
     96/**
     97 * @note: this function executes on TCPIP thread.
    8398 */
    8499static DECLCALLBACK(void) lwipCoreFiniDone(void *pvArg)
    85100{
    86     sys_sem_t *pLwipSem = (sys_sem_t *)pvArg;
    87101    LogFlowFunc(("ENTER: pvArg:%p\n", pvArg));
    88     AssertPtrReturnVoid(pvArg);
    89     lwip_sys_sem_signal(pLwipSem);
    90     LogFlowFuncLeave();
    91 }
    92 
    93 /**
    94  * @note: this function executed on TCPIP thread.
    95  */
    96 static DECLCALLBACK(void) lwipCoreUserCallback(void *pvArg)
    97 {
    98     PLWIPCOREUSERCALLBACK pUserClbk = (PLWIPCOREUSERCALLBACK)pvArg;
    99     LogFlowFunc(("ENTER: pvArg:%p\n", pvArg));
    100    
    101     if (pUserClbk->pfn)
    102         pUserClbk->pfn(pUserClbk->pvUser);
    103 
    104     /* we've finished on tcpip thread and want to wake up, waiters on EMT/main */
    105     lwip_sys_sem_signal(&g_LwipCore.LwipTcpIpSem);
    106     AssertPtrReturnVoid(pvArg);
    107     LogFlowFuncLeave();
    108 }
    109 
    110 /**
    111  * This function initialize lwip core once
    112  * further NAT instancies should just add netifs configured according
    113  * their needs.
     102
     103    /* ... fini code goes here if need be ... */
     104
     105    lwipCoreUserCallback(pvArg);
     106    LogFlowFuncLeave();
     107}
     108
     109
     110/**
     111 * This function initializes lwip core once.  Further NAT instancies
     112 * should just add netifs configured according their needs.
    114113 *
    115  * We're on EMT-n or main thread of the network service, we want execute
    116  * anything on tcpip thread.
     114 * We're on EMT-n or on the main thread of a network service, and we
     115 * want to execute something on the lwip tcpip thread.
    117116 */
    118117int vboxLwipCoreInitialize(PFNRT1 pfnCallback, void *pvCallbackArg)
     
    122121    LogFlowFuncEnter();
    123122
    124     if (!RTCritSectIsInitialized(&g_LwipCore.csLwipCore))
     123    LWIPCOREUSERCALLBACK callback;
     124    callback.pfn = pfnCallback;
     125    callback.pvUser = pvCallbackArg;
     126
    125127    {
    126         AssertReturn(g_LwipCore.iLWIPInitiatorCounter == 0, VERR_INTERNAL_ERROR);
    127         rc = RTCritSectInit(&g_LwipCore.csLwipCore);
    128 
    129         AssertRCReturn(rc, rc);
     128        RTCLock lock(g_mtxLwip);
     129
     130        if (g_LwipCore.iLWIPInitiatorCounter == 0)
     131        {
     132            lwipRc = lwip_sys_sem_new(&g_LwipCore.LwipTcpIpSem, 0);
     133            if (lwipRc != ERR_OK)
     134            {
     135                LogFlow(("%s: sys_sem_new error %d\n", __FUNCTION__, lwipRc));
     136                goto done;
     137            }
     138
     139            lwip_tcpip_init(lwipCoreInitDone, &callback);
     140        }
     141        else
     142        {
     143            lwipRc = tcpip_callback(lwipCoreUserCallback, &callback);
     144            if (lwipRc != ERR_OK)
     145            {
     146                LogFlow(("%s: tcpip_callback error %d\n", __FUNCTION__, lwipRc));
     147                goto done;
     148            }
     149        }
     150
     151        lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
     152        ++g_LwipCore.iLWIPInitiatorCounter;
    130153    }
    131 
    132     RTCritSectEnter(&g_LwipCore.csLwipCore);
    133    
    134     g_LwipCore.iLWIPInitiatorCounter++;
    135 
    136     if (g_LwipCore.iLWIPInitiatorCounter == 1)
     154  done:
     155    if (lwipRc != ERR_OK)
    137156    {
    138         lwipRc = lwip_sys_sem_new(&g_LwipCore.LwipTcpIpSem, 0);
    139         /* @todo: VERR_INTERNAL_ERROR perhaps should be replaced with right error code */
    140         if (lwipRc != ERR_OK)
    141         {
    142             rc = VERR_INTERNAL_ERROR;
    143             goto done;
    144         }
    145 
    146         lwip_tcpip_init(lwipCoreInitDone, &g_LwipCore.LwipTcpIpSem,
    147                         lwipCoreFiniDone, &g_LwipCore.LwipTcpIpSem);
    148         lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
    149     } /* end of if (g_LwipCore.iLWIPInitiatorCounter == 1) */
    150 
    151 
    152     /* tcpip thread launched */
    153     g_LwipCore.userInitClbk.pfn = pfnCallback;
    154     g_LwipCore.userInitClbk.pvUser = pvCallbackArg;
    155 
    156     lwipRc = tcpip_callback(lwipCoreUserCallback, &g_LwipCore.userInitClbk);
    157     if (lwipRc != ERR_OK)
    158     {
     157        /* @todo: map lwip error code? */
    159158        rc = VERR_INTERNAL_ERROR;
    160         goto done;
    161159    }
    162 
    163 
    164     /* we're waiting the result here */
    165     lwipRc = lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
    166     if (lwipRc != ERR_OK)
    167     {
    168         rc = VERR_INTERNAL_ERROR;
    169         goto done;
    170     }
    171    
    172 done:
    173     RTCritSectLeave(&g_LwipCore.csLwipCore);
    174160    LogFlowFuncLeaveRC(rc);
    175161    return rc;
    176162}
    177163
     164
    178165/**
    179166 * This function decrement lwip reference counter
     
    184171    int lwipRc = ERR_OK;
    185172    LogFlowFuncEnter();
    186     AssertReleaseReturnVoid(   RTCritSectIsInitialized(&g_LwipCore.csLwipCore)
    187                             && g_LwipCore.iLWIPInitiatorCounter >= 1);
    188     RTCritSectEnter(&g_LwipCore.csLwipCore);
    189    
    190     g_LwipCore.iLWIPInitiatorCounter--;
    191     g_LwipCore.userFiniClbk.pfn = pfnCallback;
    192     g_LwipCore.userFiniClbk.pvUser = pvCallbackArg;
    193    
    194     lwipRc = tcpip_callback(lwipCoreUserCallback, &g_LwipCore.userFiniClbk);
    195 
    196     if (lwipRc == ERR_OK)
    197         lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
    198    
    199     if (g_LwipCore.iLWIPInitiatorCounter == 0)
     173
     174    LWIPCOREUSERCALLBACK callback;
     175    callback.pfn = pfnCallback;
     176    callback.pvUser = pvCallbackArg;
     177
    200178    {
    201         tcpip_terminate();
    202         RTCritSectLeave(&g_LwipCore.csLwipCore);
    203         RTCritSectDelete(&g_LwipCore.csLwipCore);
     179        RTCLock lock(g_mtxLwip);
     180
     181        if (g_LwipCore.iLWIPInitiatorCounter == 1)
     182        {
     183            /*
     184             * TCPIP_MSG_CALLBACK_TERMINATE is like a static callback,
     185             * but causes tcpip_thread() to return afterward.
     186             *
     187             * This should probably be hidden in a function inside
     188             * lwip, but for it to be static callback the semaphore
     189             * dance should also be done inside that function.  There
     190             * is tcpip_msg::sem, but it seems to be unused and may be
     191             * gone in future versions of lwip.
     192             */
     193            struct tcpip_msg msg;
     194            msg.type = TCPIP_MSG_CALLBACK_TERMINATE;
     195            msg.msg.cb.function = lwipCoreFiniDone;
     196            msg.msg.cb.ctx = &callback;
     197
     198            lwipRc = tcpip_callbackmsg((struct tcpip_callback_msg *)&msg);
     199            if (lwipRc != ERR_OK)
     200            {
     201                LogFlow(("%s: tcpip_callback_msg error %d\n", __FUNCTION__, lwipRc));
     202            }
     203        }
     204        else
     205        {
     206            lwipRc = tcpip_callback(lwipCoreUserCallback, &callback);
     207            if (lwipRc != ERR_OK)
     208            {
     209                LogFlow(("%s: tcpip_callback error %d\n", __FUNCTION__, lwipRc));
     210            }
     211        }
     212
     213        if (lwipRc == ERR_OK)
     214            lwip_sys_sem_wait(&g_LwipCore.LwipTcpIpSem, 0);
    204215    }
    205     else
    206         RTCritSectLeave(&g_LwipCore.csLwipCore);
    207 
    208     LogFlowFuncLeave();
    209 }
     216
     217    LogFlowFuncLeave();
     218}
  • trunk/src/VBox/Devices/Network/lwip-new/src/api/tcpip.c

    r47886 r48092  
    5353static tcpip_init_done_fn tcpip_init_done;
    5454static void *tcpip_init_done_arg;
    55 
    56 static tcpip_fini_done_fn tcpip_fini_done;
    57 static void *tcpip_fini_done_arg;
    58 
    5955static sys_mbox_t mbox;
    6056
     
    150146      msg->msg.cb.function(msg->msg.cb.ctx);
    151147      break;
    152 # ifdef VBOX
    153     case TCPIP_MSG_TERM:
    154       UNLOCK_TCPIP_CORE();
     148
     149#ifdef VBOX
     150    case TCPIP_MSG_CALLBACK_TERMINATE:
     151      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_TERMINATE %p\n", (void *)msg));
     152      if (msg->msg.cb.function != NULL) {
     153        msg->msg.cb.function(msg->msg.cb.ctx);
     154      }
    155155      goto terminate;
    156 # endif
     156#endif
    157157
    158158    default:
     
    162162    }
    163163  }
    164 # ifdef VBOX
     164#ifdef VBOX
    165165 terminate:
    166   if (tcpip_fini_done != NULL)
    167     tcpip_fini_done(tcpip_fini_done_arg);
     166  /* XXX: TODO: lwip cleanup? */
     167  UNLOCK_TCPIP_CORE();
    168168#endif
    169169}
     
    471471 */
    472472void
    473 #ifdef VBOX
    474 tcpip_init(tcpip_init_done_fn initfunc,
    475            void *init_arg,
    476            tcpip_fini_done_fn finifunc,
    477            void *fini_arg)
    478 #else
    479 tcpip_init(tcpip_init_done_fn initfunc,
    480              void *init_arg)
    481 #endif
     473tcpip_init(tcpip_init_done_fn initfunc, void *arg)
    482474{
    483475  lwip_init();
    484476
    485477  tcpip_init_done = initfunc;
    486   tcpip_init_done_arg = init_arg;
    487 #ifdef VBOX
    488   tcpip_fini_done = finifunc;
    489   tcpip_fini_done_arg = fini_arg;
    490 #endif
     478  tcpip_init_done_arg = arg;
    491479  if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
    492480    LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
     
    539527}
    540528
    541 # ifdef VBOX
    542 void
    543 tcpip_terminate(void)
    544 {
    545   static struct tcpip_msg msg;
    546   msg.type = TCPIP_MSG_TERM;
    547   sys_mbox_post(&mbox, &msg);
    548 }
    549 # endif
    550529#endif /* !NO_SYS */
  • trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcpip.h

    r47886 r48092  
    9292/** Function prototype for functions passed to tcpip_callback() */
    9393typedef void (*tcpip_callback_fn)(void *ctx);
    94 # ifdef VBOX
    95 /** Function prototype for the fini_done function passed to tcpip_fini */
    96 typedef void (*tcpip_fini_done_fn)(void *arg);
    97 # endif
     94
    9895/* Forward declarations */
    9996struct tcpip_callback_msg;
    10097
    101 # ifdef VBOX
    102 /* The way vbox inform TCPIP thread to finalize ones activity. */
    103 void tcpip_terminate(void);
    104 void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *init_arg, tcpip_fini_done_fn tcpip_fini_done, void *fini_arg);
    105 # else
    10698void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg);
    107 # endif
    10899
    109100#if LWIP_NETCONN
     
    154145  TCPIP_MSG_CALLBACK_STATIC
    155146#ifdef VBOX
    156   ,
    157   TCPIP_MSG_TERM /* VBOX termination message */
     147  /* like CALLBACK_STATIC, but then makes tcpip_thread() return */
     148  , TCPIP_MSG_CALLBACK_TERMINATE
    158149#endif
    159 
    160150};
    161151
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