示例#1
0
文件: vboxhgsmi.c 项目: jeppeter/vbox
void crVBoxHGSMITearDown(void)
{
    int32_t i, cCons;

    Assert(0);

    if (!g_crvboxhgsmi.initialized) return;

    /* Connection count would be changed in calls to crNetDisconnect, so we have to store original value.
     * Walking array backwards is not a good idea as it could cause some issues if we'd disconnect clients not in the
     * order of their connection.
     */
    cCons = g_crvboxhgsmi.num_conns;
    for (i=0; i<cCons; i++)
    {
        /* Note that [0] is intended, as the connections array would be shifted in each call to crNetDisconnect */
        crNetDisconnect(g_crvboxhgsmi.conns[0]);
    }
    CRASSERT(0==g_crvboxhgsmi.num_conns);

#ifdef CHROMIUM_THREADSAFE
    crFreeMutex(&g_crvboxhgsmi.mutex);
    crFreeMutex(&g_crvboxhgsmi.recvmutex);
#endif

    if (g_crvboxhgsmi.mempool)
        crBufferPoolCallbackFree(g_crvboxhgsmi.mempool, _crVBoxHGSMISysMemFree);
    g_crvboxhgsmi.mempool = NULL;

    g_crvboxhgsmi.initialized = 0;

    crFree(g_crvboxhgsmi.conns);
    g_crvboxhgsmi.conns = NULL;
}
示例#2
0
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason) 
    {
        case DLL_PROCESS_ATTACH:
        {
            crInitMutex(&_PackMutex);
            break;
        }

        case DLL_PROCESS_DETACH:
        {
            crFreeMutex(&_PackMutex);
            crNetTearDown();
            break;
        }

        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        default:
            break;
    }

    return TRUE;
}
示例#3
0
static int
packSPUCleanup(void)
{
    int i;
#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&_PackMutex);
#endif
    for (i=0; i<MAX_THREADS; ++i)
    {
        if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer)
        {
            crPackDeleteContext(pack_spu.thread[i].packer);
        }
    }

    crFreeTSD(&_PackerTSD);
    crFreeTSD(&_PackTSD);
    
#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&_PackMutex);
# ifndef WINDOWS
    crFreeMutex(&_PackMutex);
# endif
#endif
    return 1;
}
/**
 * This routine is called when a context or thread is done with a DLM.
 * It maintains an internal count of users, and will only actually destroy
 * itself when no one is still using the DLM.
 */
void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable)
{
    /* We're about to change the displayLists hash; lock it first */
    DLM_LOCK(dlm)

    /* Decrement the user count.  If the user count has gone to
     * 0, then free the rest of the DLM.  Otherwise, other
     * contexts or threads are still using this DLM; keep
     * it around.
     */
    dlm->userCount--;
    if (dlm->userCount == 0) {

	crFreeHashtableEx(dlm->displayLists, crdlmFreeDisplayListResourcesCb, dispatchTable);
	dlm->displayLists = NULL;

	/* Must unlock before freeing the mutex */
	DLM_UNLOCK(dlm)

#ifdef CHROMIUM_THREADSAFE
	/* We release the mutex here; we really should delete the
	 * thread data key, but there's no utility in Chromium to
	 * do this.
	 *
	 * Note that, should one thread release the entire DLM
	 * while other threads still believe they are using it,
	 * any other threads that have current display lists (i.e.
	 * have issued glNewList more recently than glEndList)
	 * will be unable to reclaim their (likely very large)
	 * content buffers, as there will be no way to reclaim
	 * the thread-specific data.
	 *
	 * On the other hand, if one thread really does release
	 * the DLM while other threads still believe they are 
	 * using it, unreclaimed memory is the least of the
	 * application's problems...
	 */
	crFreeMutex(&(dlm->dlMutex));

	/* We free the TSD key here as well.  Note that this will
	 * strand any threads that still have thread-specific data
	 * tied to this key; but as stated above, if any threads
	 * still do have thread-specific data attached to this DLM,
	 * they're in big trouble anyway.
	 */
	crFreeTSD(&(dlm->tsdKey));
	crFreeTSD(&CRDLMTSDKey);
#endif

	/* Free the master record, and we're all done. */
	crFree(dlm);
    }
    else {
	/* We're keeping the DLM around for other users.  Unlock it,
	 * but retain its memory and display lists.
	 */
	DLM_UNLOCK(dlm)
    }
}
示例#5
0
/**
 * Tear down a network connection (close the socket, etc).
 */
void crNetDisconnect( CRConnection *conn )
{
    conn->Disconnect( conn );
    crFree( conn->hostname );
#ifdef CHROMIUM_THREADSAFE
    crFreeMutex( &conn->messageList.lock );
#endif
    crFree( conn );
}
示例#6
0
文件: sdp.c 项目: boompig/chromium
static void
crSDPDoDisconnect( CRConnection *conn )
{
	int num_conns = cr_sdp.num_conns;
	int none_left = 1;
	int i;

	/* If this connection has already been disconnected (e.g.
	 * if the connection has been lost and disabled through
	 * a call to __sdp_dead_connection(), which will then
	 * call this routine), don't disconnect it again; if we
	 * do, and if a new valid connection appears in the same
	 * slot (conn->index), we'll effectively disable the
	 * valid connection by mistake, leaving us unable to
	 * receive inbound data on that connection.
	 */
	if (conn->type == CR_NO_CONNECTION) return;
  
	crCloseSocket( conn->sdp_socket );
	conn->sdp_socket = 0;
	conn->type = CR_NO_CONNECTION;
	cr_sdp.conns[conn->index] = NULL;
  
	for (i = 0; i < num_conns; i++) 
	{
		if ( cr_sdp.conns[i] && cr_sdp.conns[i]->type != CR_NO_CONNECTION )
			none_left = 0; /* found a live connection */
	}
  
	if (none_left && cr_sdp.server_sock != -1)
	{
		crDebug("Closing master socket (probably quitting).");
		crCloseSocket( cr_sdp.server_sock );
#ifdef CHROMIUM_THREADSAFE
		crFreeMutex(&cr_sdp.mutex);
		crFreeMutex(&cr_sdp.recvmutex);
#endif
		crBufferPoolFree( cr_sdp.bufpool );
		cr_sdp.bufpool = NULL;
		last_port = 0;
		cr_sdp.initialized = 0;
	}
}
示例#7
0
void crFreeHashtable( CRHashTable *hash, CRHashtableCallback deleteFunc )
{
    int i;
    CRHashNode *entry, *next;

    if ( !hash) return;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&hash->mutex);
#endif

    for ( i = 0; i < CR_NUM_BUCKETS; i++ )
    {
        entry = hash->buckets[i];
        while (entry)
        {
            next = entry->next;
            /* Clear the key in case crHashtableDelete() is called
             * from this callback.
             */
            entry->key = 0;
            if (deleteFunc && entry->data)
            {
                (*deleteFunc)(entry->data);
            }
            crFree(entry);
            entry = next;

        }
    }
    crFreeHashIdPool( hash->idPool );

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&hash->mutex);
    crFreeMutex(&hash->mutex);
#endif

    crFree( hash );
}
示例#8
0
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason) 
    {
        case DLL_PROCESS_ATTACH:
        {
            crInitMutex(&_PackMutex);
            break;
        }

        case DLL_PROCESS_DETACH:
        {
            crFreeMutex(&_PackMutex);
            crNetTearDown();
            break;
        }

        case DLL_THREAD_ATTACH:
        {
            packspu_VBoxPackAttachThread();
            crStateOnThreadAttachDetach(GL_TRUE);
            break;
        }

        case DLL_THREAD_DETACH:
        {
            packspu_VBoxPackDetachThread();
            crStateOnThreadAttachDetach(GL_FALSE);
            break;
        }

        default:
            break;
    }

    return TRUE;
}
示例#9
0
/* Free up stuff */
void crNetTearDown()
{
    CRNetReceiveFuncList *rfl;
    CRNetCloseFuncList *cfl;
    void *tmp;

    if (!cr_net.initialized) return;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&cr_net.mutex);
#endif

    /* Note, other protocols used by chromium should free up stuff too,
     * but VBox doesn't use them, so no other checks.
     */  
    if (cr_net.use_hgcm)
        crVBoxHGCMTearDown();

    for (rfl = cr_net.recv_list ; rfl ; rfl = (CRNetReceiveFuncList *) tmp )
    {
        tmp = rfl->next;
        crFree(rfl);
    }

    for (cfl = cr_net.close_list ; cfl ; cfl = (CRNetCloseFuncList *) tmp )
    {
        tmp = cfl->next;
        crFree(cfl);
    }

    cr_net.initialized = 0;

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&cr_net.mutex);
    crFreeMutex(&cr_net.mutex);
#endif
}
示例#10
0
文件: load.c 项目: OSLL/vboxhsm
static void stubSPUSafeTearDown(void)
{
#ifdef CHROMIUM_THREADSAFE
    CRmutex *mutex;
#endif

    if (!stub_initialized) return;
    stub_initialized = 0;

#ifdef CHROMIUM_THREADSAFE
    mutex = &stub.mutex;
    crLockMutex(mutex);
#endif
    crDebug("stubSPUSafeTearDown");

#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
    stubUninstallWindowMessageHook();
# endif
#endif

#if defined(CR_NEWWINTRACK)
    crUnlockMutex(mutex);
# if defined(WINDOWS)
    if (RTThreadGetState(stub.hSyncThread)!=RTTHREADSTATE_TERMINATED)
    {
        HANDLE hNative;
        DWORD ec=0;

        hNative = OpenThread(SYNCHRONIZE|THREAD_QUERY_INFORMATION|THREAD_TERMINATE,
                             false, RTThreadGetNative(stub.hSyncThread));
        if (!hNative)
        {
            crWarning("Failed to get handle for sync thread(%#x)", GetLastError());
        }
        else
        {
            crDebug("Got handle %p for thread %#x", hNative, RTThreadGetNative(stub.hSyncThread));
        }

        ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);

        if (PostThreadMessage(RTThreadGetNative(stub.hSyncThread), WM_QUIT, 0, 0))
        {
            RTThreadWait(stub.hSyncThread, 1000, NULL);

            /*Same issue as on linux, RTThreadWait exits before system thread is terminated, which leads
             * to issues as our dll goes to be unloaded.
             *@todo
             *We usually call this function from DllMain which seems to be holding some lock and thus we have to
             * kill thread via TerminateThread.
             */
            if (WaitForSingleObject(hNative, 100)==WAIT_TIMEOUT)
            {
                crDebug("Wait failed, terminating");
                if (!TerminateThread(hNative, 1))
                {
                    crDebug("TerminateThread failed");
                }
            }
            if (GetExitCodeThread(hNative, &ec))
            {
                crDebug("Thread %p exited with ec=%i", hNative, ec);
            }
            else
            {
                crDebug("GetExitCodeThread failed(%#x)", GetLastError());
            }
        }
        else
        {
            crDebug("Sync thread killed before DLL_PROCESS_DETACH");
        }

        if (hNative)
        {
            CloseHandle(hNative);
        }
    }
#else
    if (stub.hSyncThread!=NIL_RTTHREAD)
    {
        ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
        {
            /*RTThreadWait might return too early, which cause our code being unloaded while RT thread wrapper is still running*/
            int rc = pthread_join(RTThreadGetNative(stub.hSyncThread), NULL);
            if (!rc)
            {
                crDebug("pthread_join failed %i", rc);
            }
        }
    }
#endif
    crLockMutex(mutex);
#endif

#ifndef WINDOWS
    crNetTearDown();
#endif

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(mutex);
    crFreeMutex(mutex);
#endif
    crMemset(&stub, 0, sizeof(stub));
}
示例#11
0
/**
 * Establish a connection with a server.
 * \param server  the server to connect to, in the form
 *                "protocol://servername:port" where the port specifier
 *                is optional and if the protocol is missing it is assumed
 *                to be "tcpip".
 * \param default_port  the port to connect to, if port not specified in the
 *                      server URL string.
 * \param mtu  desired maximum transmission unit size (in bytes)
 * \param broker  either 1 or 0 to indicate if connection is brokered through
 *                the mothership
 */
CRConnection * crNetConnectToServer( const char *server, unsigned short default_port, int mtu, int broker
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , struct VBOXUHGSMI *pHgsmi
#endif
)
{
    char hostname[4096], protocol[4096];
    unsigned short port;
    CRConnection *conn;

    crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d, broker=%d )",
                     server, default_port, mtu, broker );

    CRASSERT( cr_net.initialized );

    if (mtu < CR_MINIMUM_MTU)
    {
        crError( "You tried to connect to server \"%s\" with an mtu of %d, "
                         "but the minimum MTU is %d", server, mtu, CR_MINIMUM_MTU );
    }

    /* Tear the URL apart into relevant portions. */
    if ( !crParseURL( server, protocol, hostname, &port, default_port ) ) {
         crError( "Malformed URL: \"%s\"", server );
    }

    /* If the host name is "localhost" replace it with the _real_ name
     * of the localhost.  If we don't do this, there seems to be
     * confusion in the mothership as to whether or not "localhost" and
     * "foo.bar.com" are the same machine.
     */
    if (crStrcmp(hostname, "localhost") == 0) {
        int rv = crGetHostname(hostname, 4096);
        CRASSERT(rv == 0);
        (void) rv;
    }

    /* XXX why is this here???  I think it could be moved into the
     * crTeacConnection() function with no problem. I.e. change the
     * connection's port, teac_rank and tcscomm_rank there.  (BrianP)
     */
    if ( !crStrcmp( protocol, "quadrics" ) ||
         !crStrcmp( protocol, "quadrics-tcscomm" ) ) {
      /* For Quadrics protocols, treat "port" as "rank" */
      if ( port > CR_QUADRICS_HIGHEST_RANK ) {
        crWarning( "Invalid crserver rank, %d, defaulting to %d\n",
               port, CR_QUADRICS_LOWEST_RANK );
        port = CR_QUADRICS_LOWEST_RANK;
      }
    }
    crDebug( "Connecting to %s on port %d, with protocol %s",
                     hostname, port, protocol );

#ifdef SDP_SUPPORT
    /* This makes me ill, but we need to "fix" the hostname for sdp. MCH */
    if (!crStrcmp(protocol, "sdp")) {
        char* temp;
        temp = strtok(hostname, ".");
        crStrcat(temp, crGetSDPHostnameSuffix());
        crStrcpy(hostname, temp);
        crDebug("SDP rename hostname: %s", hostname);    
    }
#endif

    conn = (CRConnection *) crCalloc( sizeof(*conn) );
    if (!conn)
        return NULL;

    /* init the non-zero fields */
    conn->type               = CR_NO_CONNECTION; /* we don't know yet */
    conn->recv_credits       = CR_INITIAL_RECV_CREDITS;
    conn->hostname           = crStrdup( hostname );
    conn->port               = port;
    conn->mtu                = mtu;
    conn->buffer_size        = mtu;
    conn->broker             = broker;
    conn->endianness         = crDetermineEndianness();
    /* XXX why are these here??? Move them into the crTeacConnection()
     * and crTcscommConnection() functions.
     */
    conn->teac_id            = -1;
    conn->teac_rank          = port;
    conn->tcscomm_id         = -1;
    conn->tcscomm_rank       = port;

    crInitMessageList(&conn->messageList);

    /* now, just dispatch to the appropriate protocol's initialization functions. */
    InitConnection(conn, protocol, mtu
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , pHgsmi
#endif
            );

    if (!crNetConnect( conn ))
    {
        crDebug("crNetConnectToServer() failed, freeing the connection");
        #ifdef CHROMIUM_THREADSAFE
            crFreeMutex( &conn->messageList.lock );
        #endif
        conn->Disconnect(conn);
        crFree( conn );
        return NULL;
    }

    crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap );
    return conn;
}
void crPackDeleteContext(CRPackContext *pc)
{
    crFreeMutex(&pc->mutex);
    crFree(pc);
}