Changeset 57962 in vbox
- Timestamp:
- Sep 30, 2015 10:30:09 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r57961 r57962 1744 1744 1745 1745 /** 1746 * Creates the process for a guest session. 1747 * 1748 * 1749 * @return IPRT status code. 1750 * @param pSessionStartupInfo Session startup info. 1751 * @param pSessionThread The session thread under construction. 1752 * @param uCtrlSessionThread The session thread debug ordinal. 1753 */ 1754 static int vgsvcGstCntlSessionThreadCreateProcess(const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo, 1755 PVBOXSERVICECTRLSESSIONTHREAD pSessionThread, uint32_t uCtrlSessionThread) 1756 { 1757 /* 1758 * Is this an anonymous session? Anonymous sessions run with the same 1759 * privileges as the main VBoxService executable. 1760 */ 1761 bool const fAnonymous = pSessionThread->StartupInfo.szUser[0] == '\0'; 1762 if (fAnonymous) 1763 { 1764 Assert(!strlen(pSessionThread->StartupInfo.szPassword)); 1765 Assert(!strlen(pSessionThread->StartupInfo.szDomain)); 1766 1767 VBoxServiceVerbose(3, "New anonymous guest session ID=%RU32 created, fFlags=%x, using protocol %RU32\n", 1768 pSessionStartupInfo->uSessionID, 1769 pSessionStartupInfo->fFlags, 1770 pSessionStartupInfo->uProtocol); 1771 } 1772 else 1773 { 1774 VBoxServiceVerbose(3, "Spawning new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, fFlags=%x, using protocol %RU32\n", 1775 pSessionStartupInfo->uSessionID, 1776 pSessionStartupInfo->szUser, 1777 #ifdef DEBUG 1778 pSessionStartupInfo->szPassword, 1779 #else 1780 "XXX", /* Never show passwords in release mode. */ 1781 #endif 1782 pSessionStartupInfo->szDomain, 1783 pSessionStartupInfo->fFlags, 1784 pSessionStartupInfo->uProtocol); 1785 } 1786 1787 /* 1788 * Spawn a child process for doing the actual session handling. 1789 * Start by assembling the argument list. 1790 */ 1791 int rc = VINF_SUCCESS; 1792 char szExeName[RTPATH_MAX]; 1793 char *pszExeName = RTProcGetExecutablePath(szExeName, sizeof(szExeName)); 1794 if (pszExeName) 1795 { 1796 char szParmSessionID[32]; 1797 RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32", pSessionThread->StartupInfo.uSessionID); 1798 1799 char szParmSessionProto[32]; 1800 RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32", 1801 pSessionThread->StartupInfo.uProtocol); 1802 #ifdef DEBUG 1803 char szParmThreadId[32]; 1804 RTStrPrintf(szParmThreadId, sizeof(szParmThreadId), "--thread-id=%RU32", uCtrlSessionThread); 1805 #endif 1806 int idxArg = 0; /* Next index in argument vector. */ 1807 char const *apszArgs[24]; 1808 1809 apszArgs[idxArg++] = pszExeName; 1810 apszArgs[idxArg++] = "guestsession"; 1811 apszArgs[idxArg++] = szParmSessionID; 1812 apszArgs[idxArg++] = szParmSessionProto; 1813 #ifdef DEBUG 1814 apszArgs[idxArg++] = szParmThreadId; 1815 #endif 1816 if (!fAnonymous) /* Do we need to pass a user name? */ 1817 { 1818 apszArgs[idxArg++] = "--user"; 1819 apszArgs[idxArg++] = pSessionThread->StartupInfo.szUser; 1820 } 1821 1822 /* Add same verbose flags as parent process. */ 1823 char szParmVerbose[32]; 1824 if (g_cVerbosity > 0) 1825 { 1826 unsigned cVs = RT_MIN(g_cVerbosity, RT_ELEMENTS(szParmVerbose) - 2); 1827 szParmVerbose[0] = '-'; 1828 memset(&szParmVerbose[1], 'v', cVs); 1829 szParmVerbose[1 + cVs] = '\0'; 1830 apszArgs[idxArg++] = szParmVerbose; 1831 } 1832 1833 /* Add log file handling. Each session will have an own 1834 * log file, naming based on the parent log file. */ 1835 char szParmLogFile[sizeof(g_szLogFile) + 128]; 1836 if (g_szLogFile) 1837 { 1838 const char *pszSuffix = RTPathSuffix(g_szLogFile); 1839 if (!pszSuffix) 1840 pszSuffix = strchr(g_szLogFile, '\0'); 1841 size_t cchBase = pszSuffix - g_szLogFile; 1842 #ifndef DEBUG 1843 RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%s%s", 1844 cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, pszSuffix); 1845 #else 1846 RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%RU32-%s%s", 1847 cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, uCtrlSessionThread, 1848 pSessionStartupInfo->szUser, pszSuffix); 1849 #endif 1850 apszArgs[idxArg++] = "--logfile"; 1851 apszArgs[idxArg++] = szParmLogFile; 1852 } 1853 1854 #ifdef DEBUG 1855 VBoxServiceVerbose(4, "Argv building rc=%Rrc, session flags=%x\n", rc, g_Session.fFlags); 1856 if (RT_SUCCESS(rc)) 1857 { 1858 if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT) 1859 apszArgs[idxArg++] = "--dump-stdout"; 1860 if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR) 1861 apszArgs[idxArg++] = "--dump-stderr"; 1862 } 1863 #endif 1864 apszArgs[idxArg] = NULL; 1865 Assert(idxArg < RT_ELEMENTS(apszArgs)); 1866 1867 if (g_cVerbosity > 3) 1868 { 1869 VBoxServiceVerbose(4, "Spawning parameters:\n"); 1870 for (idxArg = 0; apszArgs[idxArg]; idxArg++) 1871 VBoxServiceVerbose(4, "\t%s\n", apszArgs[idxArg]); 1872 } 1873 1874 /* 1875 * Configure standard handles and finally create the process. 1876 */ 1877 uint32_t fProcCreate = RTPROC_FLAGS_SERVICE 1878 #ifdef RT_OS_WINDOWS /** @todo do on unix too! */ 1879 /* Make sure to also load the profile data on a Windows guest. */ 1880 | RTPROC_FLAGS_PROFILE 1881 #endif 1882 | RTPROC_FLAGS_HIDDEN; /** @todo More flags from startup info? */ 1883 1884 #if 0 /* Pipe handling not needed (yet). */ 1885 /* Setup pipes. */ 1886 rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/, 1887 &pSession->StdIn.hChild, &pSession->StdIn.phChild, &pSession->hStdInW); 1888 if (RT_SUCCESS(rc)) 1889 { 1890 rc = GstcntlProcessSetupPipe("|", 1 /*STDOUT_FILENO*/, 1891 &pSession->StdOut.hChild, &pSession->StdOut.phChild, &pSession->hStdOutR); 1892 if (RT_SUCCESS(rc)) 1893 { 1894 rc = GstcntlProcessSetupPipe("|", 2 /*STDERR_FILENO*/, 1895 &pSession->StdErr.hChild, &pSession->StdErr.phChild, &pSession->hStdErrR); 1896 if (RT_SUCCESS(rc)) 1897 { 1898 rc = RTPollSetCreate(&pSession->hPollSet); 1899 if (RT_SUCCESS(rc)) 1900 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdInW, RTPOLL_EVT_ERROR, 1901 VBOXSERVICECTRLPIPEID_STDIN); 1902 if (RT_SUCCESS(rc)) 1903 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1904 VBOXSERVICECTRLPIPEID_STDOUT); 1905 if (RT_SUCCESS(rc)) 1906 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1907 VBOXSERVICECTRLPIPEID_STDERR); 1908 } 1909 1910 if (RT_SUCCESS(rc)) 1911 rc = RTProcCreateEx(pszExeName, apszArgs, hEnv, fProcCreate, 1912 pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild, 1913 !fAnonymous ? pSession->StartupInfo.szUser : NULL, 1914 !fAnonymous ? pSession->StartupInfo.szPassword : NULL, 1915 &pSession->hProcess); 1916 1917 if (RT_SUCCESS(rc)) 1918 { 1919 /* 1920 * Close the child ends of any pipes and redirected files. 1921 */ 1922 int rc2 = RTHandleClose(pSession->StdIn.phChild); AssertRC(rc2); 1923 pSession->StdIn.phChild = NULL; 1924 rc2 = RTHandleClose(pSession->StdOut.phChild); AssertRC(rc2); 1925 pSession->StdOut.phChild = NULL; 1926 rc2 = RTHandleClose(pSession->StdErr.phChild); AssertRC(rc2); 1927 pSession->StdErr.phChild = NULL; 1928 } 1929 } 1930 } 1931 #else 1932 RTHANDLE hStdIn; 1933 if (RT_SUCCESS(rc)) 1934 rc = RTFileOpenBitBucket(&hStdIn.u.hFile, RTFILE_O_READ); 1935 if (RT_SUCCESS(rc)) 1936 { 1937 hStdIn.enmType = RTHANDLETYPE_FILE; 1938 1939 RTHANDLE hStdOutAndErr; 1940 rc = RTFileOpenBitBucket(&hStdOutAndErr.u.hFile, RTFILE_O_WRITE); 1941 if (RT_SUCCESS(rc)) 1942 { 1943 hStdOutAndErr.enmType = RTHANDLETYPE_FILE; 1944 1945 rc = RTProcCreateEx(pszExeName, apszArgs, RTENV_DEFAULT, fProcCreate, 1946 &hStdIn, &hStdOutAndErr, &hStdOutAndErr, 1947 !fAnonymous ? pSessionThread->StartupInfo.szUser : NULL, 1948 !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL, 1949 &pSessionThread->hProcess); 1950 1951 RTFileClose(hStdOutAndErr.u.hFile); 1952 } 1953 1954 RTFileClose(hStdIn.u.hFile); 1955 } 1956 #endif 1957 } 1958 else 1959 rc = VERR_FILE_NOT_FOUND; 1960 return rc; 1961 } 1962 1963 1964 /** 1746 1965 * Creates a guest session. 1747 1966 * … … 1785 2004 * Allocate and initialize the session thread structure. 1786 2005 */ 1787 PVBOXSERVICECTRLSESSIONTHREAD pSessionThread = 1788 (PVBOXSERVICECTRLSESSIONTHREAD)RTMemAllocZ(sizeof(VBOXSERVICECTRLSESSIONTHREAD)); 2006 PVBOXSERVICECTRLSESSIONTHREAD pSessionThread = (PVBOXSERVICECTRLSESSIONTHREAD)RTMemAllocZ(sizeof(*pSessionThread)); 1789 2007 if (pSessionThread) 1790 2008 { … … 1796 2014 pSessionThread->fStopped = false; 1797 2015 1798 /* Is this an anonymous session? */1799 /* Anonymous sessions run with the same privileges as the main VBoxService executable. */1800 bool const fAnonymous = pSessionThread->StartupInfo.szUser[0] == '\0';1801 if (fAnonymous)1802 {1803 Assert(!strlen(pSessionThread->StartupInfo.szPassword));1804 Assert(!strlen(pSessionThread->StartupInfo.szDomain));1805 1806 VBoxServiceVerbose(3, "New anonymous guest session ID=%RU32 created, fFlags=%x, using protocol %RU32\n",1807 pSessionStartupInfo->uSessionID,1808 pSessionStartupInfo->fFlags,1809 pSessionStartupInfo->uProtocol);1810 }1811 else1812 {1813 VBoxServiceVerbose(3, "Spawning new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, fFlags=%x, using protocol %RU32\n",1814 pSessionStartupInfo->uSessionID,1815 pSessionStartupInfo->szUser,1816 #ifdef DEBUG1817 pSessionStartupInfo->szPassword,1818 #else1819 "XXX", /* Never show passwords in release mode. */1820 #endif1821 pSessionStartupInfo->szDomain,1822 pSessionStartupInfo->fFlags,1823 pSessionStartupInfo->uProtocol);1824 }1825 1826 2016 rc = RTCritSectInit(&pSessionThread->CritSect); 1827 AssertRC(rc); /* We'll check this again further down, right... */ 1828 1829 /** @todo r=bird: split function here, that would simplify failure cleanup... */ 1830 /* 1831 * Spawn a child process for doing the actual session handling. 1832 * Start by assembling the argument list. 1833 */ 1834 char szExeName[RTPATH_MAX]; 1835 char *pszExeName = RTProcGetExecutablePath(szExeName, sizeof(szExeName)); 1836 if (pszExeName) 1837 { 1838 char szParmSessionID[32]; 1839 RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32", pSessionThread->StartupInfo.uSessionID); 1840 1841 char szParmSessionProto[32]; 1842 RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32", 1843 pSessionThread->StartupInfo.uProtocol); 1844 #ifdef DEBUG 1845 char szParmThreadId[32]; 1846 RTStrPrintf(szParmThreadId, sizeof(szParmThreadId), "--thread-id=%RU32", s_uCtrlSessionThread); 1847 #endif 1848 int idxArg = 0; /* Next index in argument vector. */ 1849 char const *apszArgs[24]; 1850 1851 apszArgs[idxArg++] = pszExeName; 1852 apszArgs[idxArg++] = "guestsession"; 1853 apszArgs[idxArg++] = szParmSessionID; 1854 apszArgs[idxArg++] = szParmSessionProto; 1855 #ifdef DEBUG 1856 apszArgs[idxArg++] = szParmThreadId; 1857 #endif 1858 if (!fAnonymous) /* Do we need to pass a user name? */ 1859 { 1860 apszArgs[idxArg++] = "--user"; 1861 apszArgs[idxArg++] = pSessionThread->StartupInfo.szUser; 1862 } 1863 1864 /* Add same verbose flags as parent process. */ 1865 char szParmVerbose[32]; 1866 if (g_cVerbosity > 0) 1867 { 1868 unsigned cVs = RT_MIN(g_cVerbosity, RT_ELEMENTS(szParmVerbose) - 2); 1869 szParmVerbose[0] = '-'; 1870 memset(&szParmVerbose[1], 'v', cVs); 1871 szParmVerbose[1 + cVs] = '\0'; 1872 apszArgs[idxArg++] = szParmVerbose; 1873 } 1874 1875 /* Add log file handling. Each session will have an own 1876 * log file, naming based on the parent log file. */ 1877 char szParmLogFile[sizeof(g_szLogFile) + 128]; 1878 if (g_szLogFile) 1879 { 1880 const char *pszSuffix = RTPathSuffix(g_szLogFile); 1881 if (!pszSuffix) 1882 pszSuffix = strchr(g_szLogFile, '\0'); 1883 size_t cchBase = pszSuffix - g_szLogFile; 1884 #ifndef DEBUG 1885 RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%s%s", 1886 cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, pszSuffix); 1887 #else 1888 RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%RU32-%s%s", 1889 cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, s_uCtrlSessionThread, 1890 pSessionStartupInfo->szUser, pszSuffix); 1891 #endif 1892 apszArgs[idxArg++] = "--logfile"; 1893 apszArgs[idxArg++] = szParmLogFile; 1894 } 1895 1896 #ifdef DEBUG 1897 VBoxServiceVerbose(4, "Argv building rc=%Rrc, session flags=%x\n", rc, g_Session.fFlags); 2017 AssertRC(rc); 2018 if (RT_SUCCESS(rc)) 2019 { 2020 /* 2021 * Start the session thread. 2022 */ 2023 rc = vgsvcGstCntlSessionThreadCreateProcess(pSessionStartupInfo, pSessionThread, s_uCtrlSessionThread); 1898 2024 if (RT_SUCCESS(rc)) 1899 2025 { 1900 if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT) 1901 apszArgs[idxArg++] = "--dump-stdout"; 1902 if (g_Session.fFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR) 1903 apszArgs[idxArg++] = "--dump-stderr"; 1904 } 1905 #endif 1906 apszArgs[idxArg] = NULL; 1907 Assert(idxArg < RT_ELEMENTS(apszArgs)); 1908 1909 if (g_cVerbosity > 3) 1910 { 1911 VBoxServiceVerbose(4, "Spawning parameters:\n"); 1912 for (idxArg = 0; apszArgs[idxArg]; idxArg++) 1913 VBoxServiceVerbose(4, "\t%s\n", apszArgs[idxArg]); 1914 } 1915 1916 /* 1917 * Configure standard handles and finally create the process. 1918 */ 1919 uint32_t fProcCreate = RTPROC_FLAGS_SERVICE 1920 #ifdef RT_OS_WINDOWS /** @todo do on unix too! */ 1921 /* Make sure to also load the profile data on a Windows guest. */ 1922 | RTPROC_FLAGS_PROFILE 1923 #endif 1924 | RTPROC_FLAGS_HIDDEN; /** @todo More flags from startup info? */ 1925 1926 #if 0 /* Pipe handling not needed (yet). */ 1927 /* Setup pipes. */ 1928 rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/, 1929 &pSession->StdIn.hChild, &pSession->StdIn.phChild, &pSession->hStdInW); 1930 if (RT_SUCCESS(rc)) 1931 { 1932 rc = GstcntlProcessSetupPipe("|", 1 /*STDOUT_FILENO*/, 1933 &pSession->StdOut.hChild, &pSession->StdOut.phChild, &pSession->hStdOutR); 2026 /* 2027 * Start the session thread. 2028 */ 2029 rc = RTThreadCreateF(&pSessionThread->Thread, gstcntlSessionThread, 2030 pSessionThread /*pvUser*/, 0 /*cbStack*/, 2031 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "sess%u", s_uCtrlSessionThread); 1934 2032 if (RT_SUCCESS(rc)) 1935 2033 { 1936 rc = GstcntlProcessSetupPipe("|", 2 /*STDERR_FILENO*/, 1937 &pSession->StdErr.hChild, &pSession->StdErr.phChild, &pSession->hStdErrR); 1938 if (RT_SUCCESS(rc)) 2034 /* Wait for the thread to initialize. */ 2035 rc = RTThreadUserWait(pSessionThread->Thread, RT_MS_1MIN); 2036 if ( RT_SUCCESS(rc) 2037 && !ASMAtomicReadBool(&pSessionThread->fShutdown)) 1939 2038 { 1940 rc = RTPollSetCreate(&pSession->hPollSet); 1941 if (RT_SUCCESS(rc)) 1942 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdInW, RTPOLL_EVT_ERROR, 1943 VBOXSERVICECTRLPIPEID_STDIN); 1944 if (RT_SUCCESS(rc)) 1945 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1946 VBOXSERVICECTRLPIPEID_STDOUT); 1947 if (RT_SUCCESS(rc)) 1948 rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, 1949 VBOXSERVICECTRLPIPEID_STDERR); 2039 VBoxServiceVerbose(2, "Thread for session ID=%RU32 started\n", pSessionThread->StartupInfo.uSessionID); 2040 2041 ASMAtomicXchgBool(&pSessionThread->fStarted, true); 2042 2043 /* Add session to list. */ 2044 /* rc = */ RTListAppend(pList, &pSessionThread->Node); 2045 if (ppSessionThread) /* Return session if wanted. */ 2046 *ppSessionThread = pSessionThread; 2047 return VINF_SUCCESS; 1950 2048 } 1951 2049 1952 if (RT_SUCCESS(rc)) 1953 rc = RTProcCreateEx(pszExeName, apszArgs, hEnv, fProcCreate, 1954 pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild, 1955 !fAnonymous ? pSession->StartupInfo.szUser : NULL, 1956 !fAnonymous ? pSession->StartupInfo.szPassword : NULL, 1957 &pSession->hProcess); 1958 1959 if (RT_SUCCESS(rc)) 1960 { 1961 /* 1962 * Close the child ends of any pipes and redirected files. 1963 */ 1964 int rc2 = RTHandleClose(pSession->StdIn.phChild); AssertRC(rc2); 1965 pSession->StdIn.phChild = NULL; 1966 rc2 = RTHandleClose(pSession->StdOut.phChild); AssertRC(rc2); 1967 pSession->StdOut.phChild = NULL; 1968 rc2 = RTHandleClose(pSession->StdErr.phChild); AssertRC(rc2); 1969 pSession->StdErr.phChild = NULL; 1970 } 1971 } 1972 } 1973 #else 1974 RTHANDLE hStdIn; 1975 if (RT_SUCCESS(rc)) 1976 rc = RTFileOpenBitBucket(&hStdIn.u.hFile, RTFILE_O_READ); 1977 if (RT_SUCCESS(rc)) 1978 { 1979 hStdIn.enmType = RTHANDLETYPE_FILE; 1980 1981 RTHANDLE hStdOutAndErr; 1982 rc = RTFileOpenBitBucket(&hStdOutAndErr.u.hFile, RTFILE_O_WRITE); 1983 if (RT_SUCCESS(rc)) 1984 { 1985 hStdOutAndErr.enmType = RTHANDLETYPE_FILE; 1986 1987 rc = RTProcCreateEx(pszExeName, apszArgs, RTENV_DEFAULT, fProcCreate, 1988 &hStdIn, &hStdOutAndErr, &hStdOutAndErr, 1989 !fAnonymous ? pSessionThread->StartupInfo.szUser : NULL, 1990 !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL, 1991 &pSessionThread->hProcess); 1992 1993 RTFileClose(hStdOutAndErr.u.hFile); 1994 } 1995 1996 RTFileClose(hStdIn.u.hFile); 1997 } 1998 #endif 1999 } 2000 else 2001 rc = VERR_FILE_NOT_FOUND; 2002 2003 if (RT_SUCCESS(rc)) 2004 { 2005 /* 2006 * Start session the thread. 2007 */ 2008 rc = RTThreadCreateF(&pSessionThread->Thread, gstcntlSessionThread, 2009 pSessionThread /*pvUser*/, 0 /*cbStack*/, 2010 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "sess%u", s_uCtrlSessionThread); 2011 if (RT_FAILURE(rc)) 2012 { 2013 VBoxServiceError("Creating session thread failed, rc=%Rrc\n", rc); 2014 /** @todo r=bird: what about the process we created? Perhaps a 2015 * RTProcTerminate would be in order? */ 2016 } 2017 else 2018 { 2019 /* Wait for the thread to initialize. */ 2020 rc = RTThreadUserWait(pSessionThread->Thread, 60 * 1000 /* 60s timeout */); 2021 if ( ASMAtomicReadBool(&pSessionThread->fShutdown) 2022 || RT_FAILURE(rc)) 2023 { 2050 /* 2051 * Bail out. 2052 */ 2024 2053 VBoxServiceError("Thread for session ID=%RU32 failed to start, rc=%Rrc\n", 2025 2054 pSessionThread->StartupInfo.uSessionID, rc); 2026 if (RT_SUCCESS (rc))2055 if (RT_SUCCESS_NP(rc)) 2027 2056 rc = VERR_CANT_CREATE; /** @todo Find a better rc. */ 2028 2057 } 2029 2058 else 2059 VBoxServiceError("Creating session thread failed, rc=%Rrc\n", rc); 2060 2061 RTProcTerminate(pSessionThread->hProcess); 2062 uint32_t cMsWait = 1; 2063 while ( RTProcWait(pSessionThread->hProcess, RTPROCWAIT_FLAGS_NOBLOCK, NULL) == VERR_PROCESS_RUNNING 2064 && cMsWait <= 9) /* 1023 ms */ 2030 2065 { 2031 VBoxServiceVerbose(2, "Thread for session ID=%RU32 started\n", 2032 pSessionThread->StartupInfo.uSessionID); 2033 2034 ASMAtomicXchgBool(&pSessionThread->fStarted, true); 2035 2036 /* Add session to list. */ 2037 /* rc = */ RTListAppend(pList, &pSessionThread->Node); 2038 if (ppSessionThread) /* Return session if wanted. */ 2039 *ppSessionThread = pSessionThread; 2066 RTThreadSleep(cMsWait); 2067 cLoops <<= 2; 2040 2068 } 2041 2069 } 2042 } 2043 2044 if (RT_FAILURE(rc)) 2045 { 2046 /** @todo r=bird: what about deleting the critsect? You're leaking event 2047 * semaphore handles here. */ 2048 RTMemFree(pSessionThread); 2049 } 2070 RTCritSectDelete(&pSessionThread->CritSect); 2071 } 2072 RTMemFree(pSessionThread); 2050 2073 } 2051 2074 else
Note:
See TracChangeset
for help on using the changeset viewer.