Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 3479)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 3480)
@@ -7383,6 +7383,10 @@
 #if defined(__WIN__)
     mIPCSem = NULL;
+#elif defined(__OS2__)
+    mIPCSem = NULLHANDLE;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     mIPCSem = -1;
+#else
+# error "Port me!"
 #endif
 
@@ -7420,12 +7424,23 @@
             mIPCSemName[i] = '/';
     mIPCSem = ::CreateMutex (NULL, FALSE, mIPCSemName);
-    ComAssertMsgRet (mIPCSem, ("Cannot create IPC mutex, err=0x%08X", ::GetLastError()),
+    ComAssertMsgRet (mIPCSem,
+                     ("Cannot create IPC mutex '%ls', err=%d\n",
+                      mIPCSemName.raw(), ::GetLastError()),
+                     E_FAIL);
+#elif defined(__OS2__)
+    Utf8Str ipcSem = Utf8StrFmt ("\\SEM32\\VBOX\\VM\\{%Vuuid}",
+                                 aMachine->mData->mUuid.raw());
+    mIPCSemName = ipcSem;
+    APIRET arc = ::DosCreateMutexSem ((PSZ) ipcSem.raw(), &mIPCSem, 0, FALSE);
+    ComAssertMsgRet (arc == NO_ERROR,
+                     ("Cannot create IPC mutex '%s', arc=%ld\n",
+                      ipcSem.raw(), arc),
                      E_FAIL);
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     Utf8Str configFile = aMachine->mData->mConfigFileFull;
-    char *pszConfigFile = NULL;
-    RTStrUtf8ToCurrentCP (&pszConfigFile, configFile);
-    key_t key = ::ftok (pszConfigFile, 0);
-    RTStrFree (pszConfigFile);
+    char *configFileCP = NULL;
+    RTStrUtf8ToCurrentCP (&configFileCP, configFile);
+    key_t key = ::ftok (configFileCP, 0);
+    RTStrFree (configFileCP);
     mIPCSem = ::semget (key, 1, S_IRWXU | S_IRWXG | S_IRWXO | IPC_CREAT);
     ComAssertMsgRet (mIPCSem >= 0, ("Cannot create IPC semaphore, errno=%d", errno),
@@ -7435,4 +7450,6 @@
     ComAssertMsgRet (rv == 0, ("Cannot init IPC semaphore, errno=%d", errno),
                      E_FAIL);
+#else
+# error "Port me!"
 #endif
 
@@ -7526,8 +7543,14 @@
             ::CloseHandle (mIPCSem);
         mIPCSem = NULL;
+#elif defined(__OS2__)
+        if (mIPCSem != NULLHANDLE)
+            ::DosCloseMutexSem (mIPCSem);
+        mIPCSem = NULLHANDLE;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
         if (mIPCSem >= 0)
             ::semctl (mIPCSem, 0, IPC_RMID);
         mIPCSem = -1;
+#else
+# error "Port me!"
 #endif
         uninitDataAndChildObjects();
@@ -7668,8 +7691,14 @@
         ::CloseHandle (mIPCSem);
     mIPCSem = NULL;
+#elif defined(__OS2__)
+    if (mIPCSem != NULLHANDLE)
+        ::DosCloseMutexSem (mIPCSem);
+    mIPCSem = NULLHANDLE;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     if (mIPCSem >= 0)
         ::semctl (mIPCSem, 0, IPC_RMID);
     mIPCSem = -1;
+#else
+# error "Port me!"
 #endif
 
@@ -7722,5 +7751,5 @@
     AutoReaderLock alock (this);
 
-#if defined(__WIN__)
+#if defined(__WIN__) || defined(__OS2__)
     mIPCSemName.cloneTo (id);
     return S_OK;
@@ -7729,5 +7758,5 @@
     return S_OK;
 #else
-    return S_FAIL;
+# error "Port me!"
 #endif
 }
@@ -8431,12 +8460,11 @@
  *  process death.
  *
- *  @note On Win32, this method is called only when we've got the semaphore
- *  (i.e. it has been signaled when we were waiting for it).
- *
- *  On Win32, this method always returns true.
- *
- *  On Linux, the method returns true if the client process has terminated
- *  abnormally (and/or the session has been uninitialized) and false if it is
- *  still alive.
+ *  @note On Win32 and on OS/2, this method is called only when we've got the
+ *  mutex (i.e. the client has either died or terminated normally). This
+ *  method always returns true.
+ *
+ *  @note On Linux, the method returns true if the client process has
+ *  terminated abnormally (and/or the session has been uninitialized) and
+ *  false if it is still alive.
  *
  *  @note Locks this object for writing.
@@ -8446,5 +8474,5 @@
     Uninit::Reason reason;
     bool doUninit = false;
-    bool rc = false;
+    bool ret = false;
 
     /*
@@ -8488,5 +8516,16 @@
         doUninit = true;
 
-        rc = true;
+        ret = true;
+
+#elif defined(__OS2__)
+
+        AssertMsg (mIPCSem, ("semaphore must be created"));
+
+        /* release the IPC mutex */
+        ::DosReleaseMutexSem (mIPCSem);
+
+        doUninit = true;
+
+        ret = true;
 
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
@@ -8501,6 +8540,8 @@
         }
 
-        rc = val > 0;
-
+        ret = val > 0;
+
+#else
+# error "Port me!"
 #endif
 
@@ -8510,5 +8551,5 @@
         uninit (reason);
 
-    return rc;
+    return ret;
 }
 
Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 3479)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 3480)
@@ -37,5 +37,7 @@
  endif
  DLLS           += VBoxSVCM
- DEFS           += VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
+ ifneq ($(BUILD_TARGET),os2)
+  DEFS          += VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
+ endif
  DEFS           += VBOX_WITH_UNIXY_TAP_NETWORKING
 endif
Index: /trunk/src/VBox/Main/SessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SessionImpl.cpp	(revision 3479)
+++ /trunk/src/VBox/Main/SessionImpl.cpp	(revision 3480)
@@ -40,5 +40,5 @@
 #include <iprt/process.h>
 
-#if defined(__WIN__)
+#if defined(__WIN__) || defined (__OS2__)
 /** VM IPC mutex holder thread */
 static DECLCALLBACK(int) IPCMutexHolderThread (RTTHREAD Thread, void *pvUser);
@@ -94,6 +94,11 @@
     mIPCSem = NULL;
     mIPCThreadSem = NULL;
+#elif defined(__OS2__)
+    mIPCThread = NIL_RTTHREAD;
+    mIPCThreadSem = NIL_RTSEMEVENT;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     mIPCSem = -1;
+#else
+# error "Port me!"
 #endif
 
@@ -645,6 +650,11 @@
 #if defined(__WIN__)
         Assert (!mIPCSem && !mIPCThreadSem);
+#elif defined(__OS2__)
+        Assert (mIPCThread == NIL_RTTHREAD &&
+                mIPCThreadSem == NIL_RTSEMEVENT);
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
         Assert (mIPCSem == -1);
+#else
+# error "Port me!"
 #endif
         LogFlowThisFuncLeave();
@@ -741,7 +751,7 @@
     Bstr ipcId;
     rc = mControl->GetIPCId (ipcId.asOutParam());
-    AssertComRCReturn (rc, rc);
-
-    LogFlowThisFunc (("ipcId: {%ls}\n", ipcId.raw()));
+    AssertComRCReturnRC (rc);
+
+    LogFlowThisFunc (("ipcId='%ls'\n", ipcId.raw()));
 
 #if defined(__WIN__)
@@ -764,5 +774,5 @@
     data [2] = 0; /* will get an output from the thread */
 
-    /* create the thread to hold the IPC mutex until signalled to release it */
+    /* create a thread to hold the IPC mutex until signalled to release it */
     RTTHREAD tid;
     int vrc = RTThreadCreate (&tid, IPCMutexHolderThread, (void *) data,
@@ -772,5 +782,5 @@
     /* wait until thread init is completed */
     DWORD wrc = ::WaitForSingleObject (mIPCThreadSem, INFINITE);
-    AssertMsg (wrc == WAIT_OBJECT_0, ("Wait failed, err=%d", ::GetLastError()));
+    AssertMsg (wrc == WAIT_OBJECT_0, ("Wait failed, err=%d\n", ::GetLastError()));
     Assert (data [2]);
 
@@ -787,4 +797,31 @@
         rc = E_FAIL;
     }
+
+#elif defined(__OS2__)
+
+    /* We use XPCOM where any message (including close()) can arrive on any
+     * worker thread (which will not necessarily match this thread that opens
+     * the mutex). Therefore, we need a separate thread to hold the IPC mutex
+     * and then release it in close(). */
+
+    int vrc = RTSemEventCreate (&mIPCThreadSem);
+    AssertRCReturn (vrc, E_FAIL);
+
+    void *data [3];
+    data [0] = (void *) ipcId.raw();
+    data [1] = (void *) mIPCThreadSem;
+    data [2] = (void *) false; /* will get the thread result here */
+
+    /* create a thread to hold the IPC mutex until signalled to release it */
+    vrc = RTThreadCreate (&mIPCThread, IPCMutexHolderThread, (void *) data,
+                          0, RTTHREADTYPE_MAIN_WORKER, 0, "IPCHolder");
+    AssertRCReturn (vrc, E_FAIL);
+
+    /* wait until thread init is completed */
+    vrc = RTThreadUserWait (mIPCThread, RT_INDEFINITE_WAIT);
+    AssertReturn (VBOX_SUCCESS (vrc) || vrc == VERR_INTERRUPTED, E_FAIL);
+
+    /* the thread must succeed */
+    AssertReturn ((bool) data [2], E_FAIL);
 
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
@@ -808,4 +845,6 @@
                     E_FAIL);
 
+#else
+# error "Port me!"
 #endif
 
@@ -818,8 +857,9 @@
     /* release the IPC semaphore */
 #if defined(__WIN__)
+
     if (mIPCSem && mIPCThreadSem)
     {
         /*
-         *  say the thread holding the IPC mutex to release it;
+         *  tell the thread holding the IPC mutex to release it;
          *  it will close mIPCSem handle
          */
@@ -829,5 +869,30 @@
         ::CloseHandle (mIPCThreadSem);
     }
+
+#elif defined(__OS2__)
+
+    if (mIPCThread != NIL_RTTHREAD)
+    {
+        Assert (mIPCThreadSem != NIL_RTSEMEVENT);
+
+        /* tell the thread holding the IPC mutex to release it */
+        int vrc = RTSemEventSignal (mIPCThreadSem);
+        AssertRC (vrc == NO_ERROR);
+
+        /* wait for the thread to finish */
+        vrc = RTThreadUserWait (mIPCThread, RT_INDEFINITE_WAIT);
+        Assert (VBOX_SUCCESS (vrc) || vrc == VERR_INTERRUPTED);
+
+        mIPCThread = NIL_RTTHREAD;
+    }
+
+    if (mIPCThreadSem != NIL_RTSEMEVENT)
+    {
+        RTSemEventDestroy (mIPCThreadSem);
+        mIPCThreadSem = NIL_RTSEMEVENT;
+    }
+
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+
     if (mIPCSem >= 0)
     {
@@ -835,4 +900,7 @@
         ::semop (mIPCSem, &sop, 1);
     }
+
+#else
+# error "Port me!"
 #endif
 }
@@ -851,5 +919,5 @@
 
     HANDLE ipcMutex = ::OpenMutex (MUTEX_ALL_ACCESS, FALSE, sessionId);
-    AssertMsg (ipcMutex, ("cannot open IPC mutex, err=%08X\n", ::GetLastError()));
+    AssertMsg (ipcMutex, ("cannot open IPC mutex, err=%d\n", ::GetLastError()));
 
     if (ipcMutex)
@@ -888,2 +956,57 @@
 #endif
 
+#if defined(__OS2__) 
+/** VM IPC mutex holder thread */
+DECLCALLBACK(int) IPCMutexHolderThread (RTTHREAD Thread, void *pvUser)
+{
+    LogFlowFuncEnter();
+
+    Assert (pvUser);
+    void **data = (void **) pvUser;
+
+    Utf8Str ipcId = (BSTR) data [0];
+    RTSEMEVENT finishSem = (RTSEMEVENT) data [1];
+
+    LogFlowFunc (("ipcId='%s', finishSem=%p\n", ipcId.raw(), finishSem));
+
+    HMTX ipcMutex = NULLHANDLE;
+    APIRET arc = ::DosOpenMutexSem ((PSZ) ipcId.raw(), &ipcMutex);
+    AssertMsg (arc == NO_ERROR, ("cannot open IPC mutex, arc=%ld\n", arc));
+
+    if (arc == NO_ERROR)
+    {
+        /* grab the mutex */
+        LogFlowFunc (("grabbing IPC mutex...\n"));
+        arc = ::DosRequestMutexSem (ipcMutex, SEM_IMMEDIATE_RETURN);
+        AssertMsg (arc == NO_ERROR, ("cannot grab IPC mutex, arc=%ld\n", arc));
+        if (arc == NO_ERROR)
+        {
+            /* store the answer */
+            data [2] = (void *) true;
+            /* signal we're done */
+            int vrc = RTThreadUserSignal (Thread);
+            AssertRC (vrc);
+
+            /* wait until we're signaled to release the IPC mutex */
+            LogFlowFunc (("waiting for termination signal..\n"));
+            vrc = RTSemEventWait (finishSem, RT_INDEFINITE_WAIT);
+            Assert (arc == ERROR_INTERRUPT || ERROR_TIMEOUT);
+
+            /* release the IPC mutex */
+            LogFlowFunc (("releasing IPC mutex...\n"));
+            arc = ::DosReleaseMutexSem (ipcMutex);
+            AssertMsg (arc == NO_ERROR, ("cannot release mutex, arc=%ld\n", arc));
+        }
+    }
+
+    /* store the answer */
+    data [1] = (void *) false;
+    /* signal we're done */
+    int vrc = RTThreadUserSignal (Thread);
+    AssertRC (vrc);
+
+    LogFlowFuncLeave();
+
+    return 0;
+}
+#endif
Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 3479)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 3480)
@@ -278,9 +278,13 @@
 #if defined(__WIN__)
         unconst (mWatcherData.mUpdateReq) = ::CreateEvent (NULL, FALSE, FALSE, NULL);
+#elif defined(__OS2__)
+        RTSemEventCreate (&unconst (mWatcherData.mUpdateReq));
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+        RTSemEventCreate (&unconst (mWatcherData.mUpdateReq));
 #else
-        RTSemEventCreate (&unconst (mWatcherData.mUpdateReq));
+# error "Port me!"
 #endif
         int vrc = RTThreadCreate (&unconst (mWatcherData.mThread),
-                                  clientWatcher, (void *) this,
+                                  ClientWatcher, (void *) this,
                                   0, RTTHREADTYPE_MAIN_WORKER,
                                   RTTHREADFLAGS_WAITABLE, "Watcher");
@@ -293,5 +297,5 @@
     {
         /* start the async event handler thread */
-        int vrc = RTThreadCreate (&unconst (mAsyncEventThread), asyncEventHandler,
+        int vrc = RTThreadCreate (&unconst (mAsyncEventThread), AsyncEventHandler,
                                   &unconst (mAsyncEventQ),
                                   0, RTTHREADTYPE_MAIN_WORKER,
@@ -419,5 +423,5 @@
         unconst (mWatcherData.mUpdateReq) = NULL;
     }
-#else
+#elif defined(__OS2__)
     if (mWatcherData.mUpdateReq != NIL_RTSEMEVENT)
     {
@@ -425,4 +429,12 @@
         unconst (mWatcherData.mUpdateReq) = NIL_RTSEMEVENT;
     }
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+    if (mWatcherData.mUpdateReq != NIL_RTSEMEVENT)
+    {
+        RTSemEventDestroy (mWatcherData.mUpdateReq);
+        unconst (mWatcherData.mUpdateReq) = NIL_RTSEMEVENT;
+    }
+#else
+# error "Port me!"
 #endif
 
@@ -2394,6 +2406,10 @@
 #if defined(__WIN__)
     ::SetEvent (mWatcherData.mUpdateReq);
+#elif defined(__OS2__)
+    RTSemEventSignal (mWatcherData.mUpdateReq);
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+    RTSemEventSignal (mWatcherData.mUpdateReq);
 #else
-    RTSemEventSignal (mWatcherData.mUpdateReq);
+# error "Port me!"
 #endif
 }
@@ -4347,5 +4363,5 @@
  */
 // static
-DECLCALLBACK(int) VirtualBox::clientWatcher (RTTHREAD thread, void *pvUser)
+DECLCALLBACK(int) VirtualBox::ClientWatcher (RTTHREAD thread, void *pvUser)
 {
     LogFlowFuncEnter();
@@ -4355,5 +4371,5 @@
 
     SessionMachineVector machines;
-    int cnt = 0;
+    size_t cnt = 0;
 
 #if defined(__WIN__)
@@ -4437,11 +4453,17 @@
     ::CoUninitialize();
 
-#else
-
-    bool need_update = false;
+#elif defined (__OS2__)
+
+    /// @todo (dmik) processes reaping!
+
+    /* according to PMREF, 64 is the maximum for the muxwait list */
+    SEMRECORD handles [64];
+
+    HMUX muxSem = NULLHANDLE;
 
     do
     {
         AutoCaller autoCaller (that);
+        /* VirtualBox has been early uninitialized, terminate */
         if (!autoCaller.isOk())
             break;
@@ -4452,5 +4474,5 @@
             autoCaller.release();
 
-            int rc = RTSemEventWait (that->mWatcherData.mUpdateReq, 500);
+            int vrc = RTSemEventWait (that->mWatcherData.mUpdateReq, 500);
 
             /*
@@ -4462,4 +4484,128 @@
                 break;
 
+            bool update = false;
+
+            if (VBOX_SUCCESS (vrc))
+            {
+                /* update event is signaled */
+                update = true;
+            }
+            else
+            {
+                AssertMsg (vrc == VERR_TIMEOUT || vrc == VERR_INTERRUPTED,
+                           ("RTSemEventWait returned %Vrc\n", vrc));
+
+                /* are there any mutexes? */
+                if (cnt > 0)
+                {
+                    /* figure out what's going on with machines */
+
+                    unsigned long semId = 0;
+                    APIRET arc = ::DosWaitMuxWaitSem (muxSem,
+                                                      SEM_IMMEDIATE_RETURN, &semId);
+
+                    if (arc == NO_ERROR)
+                    {
+                        /* machine mutex is normally released */
+                        Assert (semId >= 0 && semId < cnt);
+                        if (semId >= 0 && semId < cnt)
+                            machines [semId]->checkForDeath();
+                        update = true;
+                    }
+                    else if (arc == ERROR_SEM_OWNER_DIED)
+                    {
+                        /* machine mutex is abandoned due to client process
+                         * termination; find which mutex is in the Owner Died
+                         * state */
+                        for (size_t i = 0; i < cnt; ++ i)
+                        {
+                            PID pid; TID tid;
+                            unsigned long reqCnt;
+                            arc = DosQueryMutexSem ((HMTX) handles [i].hsemCur, &pid,
+                                                    &tid, &reqCnt);
+                            if (arc == ERROR_SEM_OWNER_DIED)
+                            {
+                                /* close the dead mutex as asked by PMREF */
+                                ::DosCloseMutexSem ((HMTX) handles [i].hsemCur);
+
+                                Assert (i >= 0 && i < cnt);
+                                if (i >= 0 && i < cnt)
+                                    machines [i]->checkForDeath();
+                            }
+                        }
+                        update = true;
+                    }
+                    else
+                        AssertMsg (arc == ERROR_INTERRUPT || arc == ERROR_TIMEOUT,
+                                   ("DosWaitMuxWaitSem returned %d\n", arc));
+                }
+            }
+
+            if (update)
+            {
+                /* close the old muxsem */
+                if (muxSem != NULLHANDLE)
+                    ::DosCloseMuxWaitSem (muxSem);
+                /* obtain a new set of opened machines */
+                that->getOpenedMachines (machines);
+                cnt = machines.size();
+                LogFlowFunc (("UPDATE: direct session count = %d\n", cnt));
+                /// @todo use several muxwait sems if cnt is > 64
+                AssertMsg (cnt <= 64 /* according to PMREF */,
+                           ("maximum of 64 mutex semaphores reached (%d)", cnt));
+                if (cnt > 64)
+                    cnt = 64;
+                if (cnt > 0)
+                {
+                    /* renew the set of event handles */
+                    for (size_t i = 0; i < cnt; ++ i)
+                    {
+                        handles [i].hsemCur = (HSEM) machines [i]->ipcSem();
+                        handles [i].ulUser = i;
+                    }
+                    /* create a new muxsem */
+                    APIRET arc = ::DosCreateMuxWaitSem (NULL, &muxSem, cnt, handles,
+                                                        DCMW_WAIT_ANY);
+                    AssertMsg (arc == NO_ERROR,
+                               ("DosCreateMuxWaitSem returned %d\n", arc));
+                }
+            }
+        }
+        while (true);
+    }
+    while (0);
+
+    /* close the muxsem */
+    if (muxSem != NULLHANDLE)
+        ::DosCloseMuxWaitSem (muxSem);
+
+    /* delete the set of opened machines if any */
+    machines.clear();
+
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+
+    bool need_update = false;
+
+    do
+    {
+        AutoCaller autoCaller (that);
+        if (!autoCaller.isOk())
+            break;
+
+        do
+        {
+            /* release the caller to let uninit() ever proceed */
+            autoCaller.release();
+
+            int rc = RTSemEventWait (that->mWatcherData.mUpdateReq, 500);
+
+            /*
+             *  Restore the caller before using VirtualBox. If it fails, this
+             *  means VirtualBox is being uninitialized and we must terminate.
+             */
+            autoCaller.add();
+            if (!autoCaller.isOk())
+                break;
+
             if (VBOX_SUCCESS (rc) || need_update)
             {
@@ -4473,5 +4619,5 @@
 
             need_update = false;
-            for (int i = 0; i < cnt; i++)
+            for (size_t i = 0; i < cnt; ++ i)
                 need_update |= (machines [i])->checkForDeath();
 
@@ -4522,4 +4668,6 @@
     machines.clear();
 
+#else
+# error "Port me!"
 #endif
 
@@ -4532,5 +4680,5 @@
  */
 // static
-DECLCALLBACK(int) VirtualBox::asyncEventHandler (RTTHREAD thread, void *pvUser)
+DECLCALLBACK(int) VirtualBox::AsyncEventHandler (RTTHREAD thread, void *pvUser)
 {
     LogFlowFuncEnter();
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 3479)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 3480)
@@ -756,6 +756,9 @@
 
     bool checkForDeath();
-#ifdef __WIN__
+
+#if defined (__WIN__) 
     HANDLE ipcSem() { return mIPCSem; }
+#elif defined (__OS2__)
+    HMTX ipcSem() { return mIPCSem; }
 #endif
 
@@ -821,6 +824,11 @@
     HANDLE mIPCSem;
     Bstr mIPCSemName;
+#elif defined(__OS2__)
+    HMTX mIPCSem;
+    Bstr mIPCSemName;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     int mIPCSem;
+#else
+# error "Port me!"
 #endif
 
Index: /trunk/src/VBox/Main/include/SessionImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/SessionImpl.h	(revision 3479)
+++ /trunk/src/VBox/Main/include/SessionImpl.h	(revision 3480)
@@ -125,12 +125,15 @@
     ComPtr <IVirtualBox> mVirtualBox;
 
-    // the interprocess semaphore handle (id) for the opened machine
+    /* interprocess semaphore handle (id) for the opened machine */
 #if defined(__WIN__)
     HANDLE mIPCSem;
     HANDLE mIPCThreadSem;
+#elif defined(__OS2__)
+    RTTHREAD mIPCThread;
+    RTSEMEVENT mIPCThreadSem;
 #elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
     int mIPCSem;
 #else
-# error "PORTME"
+# error "Port me!"
 #endif
 };
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 3479)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 3480)
@@ -356,6 +356,10 @@
 #if defined(__WIN__)
             : mUpdateReq (NULL)
+#elif defined(__OS2__)
+            : mUpdateReq (NIL_RTSEMEVENT)
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+            : mUpdateReq (NIL_RTSEMEVENT)
 #else
-            : mUpdateReq (NIL_RTSEMEVENT)
+# error "Port me!"
 #endif
             , mThread (NIL_RTTHREAD) {}
@@ -364,6 +368,10 @@
 #if defined(__WIN__)
         const HANDLE mUpdateReq;
+#elif defined(__OS2__)
+        const RTSEMEVENT mUpdateReq;
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+        const RTSEMEVENT mUpdateReq;
 #else
-        const RTSEMEVENT mUpdateReq;
+# error "Port me!"
 #endif
         const RTTHREAD mThread;
@@ -382,6 +390,6 @@
     static Bstr sVersion;
 
-    static DECLCALLBACK(int) clientWatcher (RTTHREAD thread, void *pvUser);
-    static DECLCALLBACK(int) asyncEventHandler (RTTHREAD thread, void *pvUser);
+    static DECLCALLBACK(int) ClientWatcher (RTTHREAD thread, void *pvUser);
+    static DECLCALLBACK(int) AsyncEventHandler (RTTHREAD thread, void *pvUser);
 
 #ifdef __WIN__
Index: /trunk/src/VBox/Main/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/testcase/Makefile.kmk	(revision 3479)
+++ /trunk/src/VBox/Main/testcase/Makefile.kmk	(revision 3480)
@@ -27,4 +27,6 @@
  PROGRAMS.linux = tstVBoxAPILinux
  PROGRAMS.win   = tstVBoxAPIWin
+else ifeq ($(USER),dmik)
+ PROGRAMS       = tstAPI
 endif # VBOX_WITH_TESTCASES
 
Index: /trunk/src/VBox/Main/testcase/tstAPI.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 3479)
+++ /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 3480)
@@ -705,5 +705,5 @@
 #endif
 
-#if 0
+#if 1
     // open a (direct) session
     ///////////////////////////////////////////////////////////////////////////
@@ -718,5 +718,5 @@
         printf ("Opening a session for this machine...\n");
         CHECK_RC_BREAK (virtualBox->OpenSession (session, guid));
-#if 0
+#if 1
         ComPtr <IMachine> sessionMachine;
         printf ("Getting sessioned machine object...\n");
@@ -763,4 +763,6 @@
         }
 #endif
+        printf("Press enter to close session...");
+        getchar();
         session->Close();
     }
