Changeset 48092 in vbox for trunk/src/VBox
- Timestamp:
- Aug 27, 2013 4:35:28 PM (11 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/VBoxLwipCore.cpp
r48048 r48092 30 30 /* @todo: lwip or nat ? */ 31 31 #define LOG_GROUP LOG_GROUP_DRV_NAT 32 #include <iprt/c ritsect.h>32 #include <iprt/cpp/lock.h> 33 33 #include <iprt/timer.h> 34 34 #include <VBox/err.h> … … 52 52 53 53 54 RTCLockMtx g_mtxLwip; 55 54 56 typedef struct LWIPCORE 55 57 { 56 58 int iLWIPInitiatorCounter; 57 /* semaphore to coordinate 'tcpip' thread initialization */58 59 sys_sem_t LwipTcpIpSem; 59 /* Initalization user defined callback */60 LWIPCOREUSERCALLBACK userInitClbk;61 /* Finitialization user defined callback */62 LWIPCOREUSERCALLBACK userFiniClbk;63 RTCRITSECT csLwipCore;64 60 } LWIPCORE; 65 61 … … 68 64 69 65 /** 70 * @note: this function executed on TCPIP thread. 66 * @note: this function executes on TCPIP thread. 67 */ 68 static 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. 71 84 */ 72 85 static DECLCALLBACK(void) lwipCoreInitDone(void *pvArg) 73 86 { 74 sys_sem_t *pLwipSem = (sys_sem_t *)pvArg;75 87 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. 83 98 */ 84 99 static DECLCALLBACK(void) lwipCoreFiniDone(void *pvArg) 85 100 { 86 sys_sem_t *pLwipSem = (sys_sem_t *)pvArg;87 101 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. 114 113 * 115 * We're on EMT-n or main thread of the network service, we want execute116 * anything ontcpip 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. 117 116 */ 118 117 int vboxLwipCoreInitialize(PFNRT1 pfnCallback, void *pvCallbackArg) … … 122 121 LogFlowFuncEnter(); 123 122 124 if (!RTCritSectIsInitialized(&g_LwipCore.csLwipCore)) 123 LWIPCOREUSERCALLBACK callback; 124 callback.pfn = pfnCallback; 125 callback.pvUser = pvCallbackArg; 126 125 127 { 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; 130 153 } 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) 137 156 { 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? */ 159 158 rc = VERR_INTERNAL_ERROR; 160 goto done;161 159 } 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);174 160 LogFlowFuncLeaveRC(rc); 175 161 return rc; 176 162 } 177 163 164 178 165 /** 179 166 * This function decrement lwip reference counter … … 184 171 int lwipRc = ERR_OK; 185 172 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 200 178 { 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); 204 215 } 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 53 53 static tcpip_init_done_fn tcpip_init_done; 54 54 static void *tcpip_init_done_arg; 55 56 static tcpip_fini_done_fn tcpip_fini_done;57 static void *tcpip_fini_done_arg;58 59 55 static sys_mbox_t mbox; 60 56 … … 150 146 msg->msg.cb.function(msg->msg.cb.ctx); 151 147 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 } 155 155 goto terminate; 156 # 156 #endif 157 157 158 158 default: … … 162 162 } 163 163 } 164 # 164 #ifdef VBOX 165 165 terminate: 166 if (tcpip_fini_done != NULL)167 tcpip_fini_done(tcpip_fini_done_arg);166 /* XXX: TODO: lwip cleanup? */ 167 UNLOCK_TCPIP_CORE(); 168 168 #endif 169 169 } … … 471 471 */ 472 472 void 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 473 tcpip_init(tcpip_init_done_fn initfunc, void *arg) 482 474 { 483 475 lwip_init(); 484 476 485 477 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; 491 479 if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { 492 480 LWIP_ASSERT("failed to create tcpip_thread mbox", 0); … … 539 527 } 540 528 541 # ifdef VBOX542 void543 tcpip_terminate(void)544 {545 static struct tcpip_msg msg;546 msg.type = TCPIP_MSG_TERM;547 sys_mbox_post(&mbox, &msg);548 }549 # endif550 529 #endif /* !NO_SYS */ -
trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcpip.h
r47886 r48092 92 92 /** Function prototype for functions passed to tcpip_callback() */ 93 93 typedef 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 98 95 /* Forward declarations */ 99 96 struct tcpip_callback_msg; 100 97 101 # ifdef VBOX102 /* 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 # else106 98 void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); 107 # endif108 99 109 100 #if LWIP_NETCONN … … 154 145 TCPIP_MSG_CALLBACK_STATIC 155 146 #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 158 149 #endif 159 160 150 }; 161 151
Note:
See TracChangeset
for help on using the changeset viewer.