ClientTokenHolder.cpp revision 5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18f
/** @file
*
* VirtualBox API client token holder (in the client process)
*/
/*
* Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include <iprt/semaphore.h>
# include <errno.h>
#endif
#include "ClientTokenHolder.h"
#include "SessionImpl.h"
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
/** client token holder thread */
#endif
{
}
{
/* release the client token */
#if defined(RT_OS_WINDOWS)
if (mSem && mThreadSem)
{
/*
* tell the thread holding the token to release it;
* it will close mSem handle
*/
/* wait for the thread to finish */
mThreadSem = NULL;
}
if (mThread != NIL_RTTHREAD)
{
/* tell the thread holding the token to release it */
/* wait for the thread to finish */
}
if (mSem != NIL_RTSEMEVENT)
{
}
#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
if (mSem >= 0)
{
mSem = -1;
}
#else
# error "Port me!"
#endif
}
{
#if defined(RT_OS_WINDOWS)
/*
* Since there is no guarantee that the constructor and destructor will be
* called in the same thread, we need a separate thread to hold the token.
*/
("Cannot create an event sem, err=%d", ::GetLastError()));
void *data[3];
/* create a thread to hold the token until signalled to release it */
int vrc = RTThreadCreate(&mThread, ClientTokenHolderThread, (void*)data, 0, RTTHREADTYPE_MAIN_WORKER, 0, "IPCHolder");
/* wait until thread init is completed */
{
/* memorize the event sem we should signal in close() */
}
else
{
mThreadSem = NULL;
}
/*
* Since there is no guarantee that the constructor and destructor will be
* called in the same thread, we need a separate thread to hold the token.
*/
void *data[3];
/* create a thread to hold the token until signalled to release it */
0, RTTHREADTYPE_MAIN_WORKER, 0, "IPCHolder");
/* wait until thread init is completed */
/* the thread must succeed */
#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
AssertMsgReturnVoid(key != 0,
("Key value of 0 is not valid for client token"));
# else /* !VBOX_WITH_NEW_SYS_V_KEYGEN */
char *pszSemName = NULL;
# endif /* !VBOX_WITH_NEW_SYS_V_KEYGEN */
AssertMsgReturnVoid(s >= 0,
("Cannot open semaphore, errno=%d", errno));
/* grab the semaphore */
AssertMsgReturnVoid(rv == 0,
("Cannot grab semaphore, errno=%d", errno));
mSem = s;
#else
# error "Port me!"
#endif
}
{
}
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
/** client token holder thread */
{
# if defined(RT_OS_WINDOWS)
if (mutex)
{
/* grab the token */
if (wrc == WAIT_OBJECT_0)
{
if (finishSem)
{
/* signal we're done with init */
::SetEvent(initDoneSem);
/* wait until we're signaled to release the token */
/* release the token */
LogFlow(("ClientTokenHolderThread(): releasing token...\n"));
::CloseHandle(mutex);
::CloseHandle(finishSem);
}
}
}
/* signal we're done */
::SetEvent(initDoneSem);
{
/* grab the token */
LogFlowFunc(("grabbing token...\n"));
{
/* store the answer */
data[2] = (void*)true;
/* signal we're done */
/* wait until we're signaled to release the token */
LogFlowFunc(("waiting for termination signal..\n"));
/* release the token */
LogFlowFunc(("releasing token...\n"));
}
}
/* store the answer */
data[1] = (void*)false;
/* signal we're done */
# else
# error "Port me!"
# endif
return 0;
}
#endif
/* vi: set tabstop=4 shiftwidth=4 expandtab: */