Index: /trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp	(revision 49841)
+++ /trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp	(revision 49842)
@@ -93,5 +93,4 @@
 
     int                 init();
-    int                 run(void);
     void                usage(void) { /* XXX: document options */ };
     int                 parseOpt(int rc, const RTGETOPTUNION& getOptVal);
@@ -283,16 +282,4 @@
 }
 
-/**
- * Runs the DHCP server.
- *
- * @returns exit code + error message to stderr on failure, won't return on
- *          success (you must kill this process).
- */
-int VBoxNetDhcp::run(void)
-{
-    doReceiveLoop();
-    return 0;
-}
-
 
 int  VBoxNetDhcp::processUDP(void *pv, size_t cbPv)
@@ -306,5 +293,9 @@
     {
         m_uCurMsgType = uMsgType;
-        handleDhcpMsg(uMsgType, pDhcpMsg, cbPv);
+        {
+            /* To avoid fight with event processing thread */
+            VBoxNetALock(this);
+            handleDhcpMsg(uMsgType, pDhcpMsg, cbPv);
+        }
         m_uCurMsgType = UINT8_MAX;
     }
@@ -565,4 +556,5 @@
 
         {
+            VBoxNetALock(this);   
             ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
             confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
Index: /trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp	(revision 49841)
+++ /trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp	(revision 49842)
@@ -18,4 +18,5 @@
 #include "winutils.h"
 
+#include <VBox/com/assert.h>
 #include <VBox/com/com.h>
 #include <VBox/com/listeners.h>
@@ -26,5 +27,4 @@
 #include <VBox/com/errorprint.h>
 #include <VBox/com/VirtualBox.h>
-#include <VBox/com/NativeEventQueue.h>
 
 #include <iprt/net.h>
@@ -131,5 +131,4 @@
     int run();
     virtual int init(void);
-    /* @todo: when configuration would be really needed */
     virtual int parseOpt(int rc, const RTGETOPTUNION& getOptVal);
     /* VBoxNetNAT always needs Main */
@@ -151,6 +150,4 @@
     uint16_t m_u16Mtu;
     netif m_LwipNetIf;
-    /* thread where we're waiting for a frames, no semaphores needed */
-    RTTHREAD hThrIntNetRecv;
 
     /* Our NAT network descriptor in Main */
@@ -187,4 +184,7 @@
 INTNETSEG VBoxNetLwipNAT::aXmitSeg[64];
 
+/**
+ * @note: this work on Event thread.
+ */
 HRESULT VBoxNetLwipNAT::HandleEvent(VBoxEventType_T aEventType,
                                                   IEvent *pEvent)
@@ -515,23 +515,4 @@
 
 
-/**
- * Intnet-recv thread
- */
-int VBoxNetLwipNAT::intNetThreadRecv(RTTHREAD, void *)
-{
-    int rc = VINF_SUCCESS;
-
-    /* 1. initialization and connection */
-    HRESULT hrc = com::Initialize();
-    if (FAILED(hrc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
-
-    g_pLwipNat->doReceiveLoop();
-    /* 3. deinitilization and termination */
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-
 err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf)
 {
@@ -699,4 +680,7 @@
 
 
+/** This method executed on main thread, only at the end threr're one threads started explcitly (LWIP and later in ::run()
+ * RECV) 
+ */
 int VBoxNetLwipNAT::init()
 {
@@ -808,16 +792,6 @@
     }
 
+    /* this starts LWIP thread */
     vboxLwipCoreInitialize(VBoxNetLwipNAT::onLwipTcpIpInit, this);
-
-    rc = RTThreadCreate(&g_pLwipNat->hThrIntNetRecv, /* thread handle*/
-                        VBoxNetLwipNAT::intNetThreadRecv,  /* routine */
-                        NULL, /* user data */
-                        128 * _1K, /* stack size */
-                        RTTHREADTYPE_IO, /* type */
-                        0, /* flags, @todo: waitable ?*/
-                        "INTNET-RECV");
-    AssertRCReturn(rc,rc);
-
-
 
     LogFlowFuncLeaveRC(rc);
@@ -963,13 +937,6 @@
 int VBoxNetLwipNAT::run()
 {
-    /* EventQueue processing from VBoxHeadless.cpp */
-    com::NativeEventQueue         *gEventQ = NULL;
-    gEventQ = com::NativeEventQueue::getMainEventQueue();
-    while(true)
-    {
-        /* XXX:todo: graceful termination */
-        gEventQ->processEventQueue(0);
-        gEventQ->processEventQueue(500);
-    }
+    /* Father starts receiving thread and enter event loop. */
+    VBoxNetBaseService::run();
 
     vboxLwipCoreFinalize(VBoxNetLwipNAT::onLwipTcpIpFini, this);
Index: /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp	(revision 49841)
+++ /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp	(revision 49842)
@@ -29,6 +29,6 @@
 #include <VBox/com/ErrorInfo.h>
 #include <VBox/com/errorprint.h>
-#include <VBox/com/EventQueue.h>
 #include <VBox/com/VirtualBox.h>
+#include <VBox/com/NativeEventQueue.h>
 
 #include <iprt/alloca.h>
@@ -44,4 +44,5 @@
 #include <iprt/string.h>
 #include <iprt/time.h>
+#include <iprt/thread.h>
 #include <iprt/mem.h>
 #include <iprt/message.h>
@@ -83,5 +84,8 @@
       m_pIfBuf(NULL),
       m_cVerbosity(0),
-      m_fNeedMain(false)
+      m_fNeedMain(false),
+      m_EventQ(NULL),
+      m_hThrRecv(NIL_RTTHREAD),
+      fShutdown(false)
     {
         int rc = RTCritSectInit(&m_csThis);
@@ -113,4 +117,12 @@
     /* Controls whether service will connect SVC for runtime needs */
     bool                m_fNeedMain;
+    /* Event Queue */
+    com::NativeEventQueue  *m_EventQ;
+
+    /** receiving thread, used only if main is used */
+    RTTHREAD m_hThrRecv;
+
+    bool fShutdown;
+    static int recvLoop(RTTHREAD, void *);
 };
 
@@ -133,4 +145,17 @@
 
 
+int VBoxNetBaseService::Data::recvLoop(RTTHREAD, void *pvUser)
+{
+    VBoxNetBaseService *pThis = static_cast<VBoxNetBaseService *>(pvUser);
+
+    HRESULT hrc = com::Initialize();
+    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
+
+    pThis->doReceiveLoop();
+
+    return VINF_SUCCESS;
+}
+
+
 VBoxNetBaseService::VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName):m(NULL)
 {
@@ -149,4 +174,5 @@
     if (m != NULL)
     {
+        shutdown();
         if (m->m_hIf != INTNET_HANDLE_INVALID)
         {
@@ -193,4 +219,20 @@
 {
     return m->m_fNeedMain;
+}
+
+
+int VBoxNetBaseService::run()
+{
+    /**
+     * If child class need Main we start receving thread which calls doReceiveLoop and enter to event polling loop
+     * and for the rest clients we do receiving on the current (main) thread.
+     */
+    if (isMainNeeded())
+        return startReceiveThreadAndEnterEventLoop();
+    else
+    {
+        doReceiveLoop();
+        return VINF_SUCCESS;
+    }
 }
 
@@ -414,4 +456,7 @@
 void VBoxNetBaseService::shutdown(void)
 {
+    syncEnter();
+    m->fShutdown = true;
+    syncLeave();
 }
 
@@ -678,4 +723,35 @@
 
 
+int VBoxNetBaseService::startReceiveThreadAndEnterEventLoop()
+{
+    AssertMsgReturn(isMainNeeded(), ("It's expected that we need Main"), VERR_INTERNAL_ERROR);
+        
+    /* start receiving thread */
+    int rc = RTThreadCreate(&m->m_hThrRecv, /* thread handle*/
+                            &VBoxNetBaseService::Data::recvLoop,  /* routine */
+                            this, /* user data */
+                            128 * _1K, /* stack size */
+                            RTTHREADTYPE_IO, /* type */
+                            0, /* flags, @todo: waitable ?*/
+                            "RECV");
+    AssertRCReturn(rc,rc);
+
+    m->m_EventQ = com::NativeEventQueue::getMainEventQueue();
+    AssertPtrReturn(m->m_EventQ, VERR_INTERNAL_ERROR);
+
+    while(true)
+    {
+        m->m_EventQ->processEventQueue(0);
+            
+        if (m->fShutdown)
+            break;
+
+        m->m_EventQ->processEventQueue(500);
+    }
+
+    return VINF_SUCCESS;
+}
+
+
 void VBoxNetBaseService::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
 {
Index: /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
===================================================================
--- /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h	(revision 49841)
+++ /trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h	(revision 49842)
@@ -30,6 +30,33 @@
 
 
+class VBoxNetLockee
+{
+public:
+    virtual int  syncEnter() = 0;
+    virtual int  syncLeave() = 0;
+};
+
+
+class VBoxNetALock
+{
+public:
+    VBoxNetALock(VBoxNetLockee *a_lck):m_lck(a_lck)
+    {
+        if (m_lck)
+            m_lck->syncEnter();
+    }
+
+    ~VBoxNetALock()
+    {
+        if (m_lck)
+            m_lck->syncLeave();
+    }
+
+private:
+    VBoxNetLockee *m_lck;
+};
+
 # ifndef BASE_SERVICES_ONLY 
-class VBoxNetBaseService: public VBoxNetHlpUDPService
+class VBoxNetBaseService: public VBoxNetHlpUDPService, public VBoxNetLockee
 {
 public:
@@ -48,5 +75,4 @@
                                         void const *pvData, size_t cbData) const;
     virtual void        usage(void) = 0;
-    virtual int         run(void) = 0;
     virtual int         parseOpt(int rc, const RTGETOPTUNION& getOptVal) = 0;
     virtual int         processFrame(void *, size_t) = 0;
@@ -56,4 +82,5 @@
 
     virtual int         init(void);
+    virtual int         run(void);
     virtual bool        isMainNeeded() const;
 
@@ -96,15 +123,19 @@
     virtual void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const;
 
+    private:
     void doReceiveLoop();
 
-protected:
+    /** starts receiving thread and enter event polling loop. */
+    int startReceiveThreadAndEnterEventLoop();
+
+    protected:
     /* VirtualBox instance */
     ComPtr<IVirtualBox> virtualbox;
 
-private:
+    private:
     struct Data;
     Data *m;
 
-private:
+    private:
     PRTGETOPTDEF getOptionsPtr();
 };
