void crSDPInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu ) { (void) mtu; cr_sdp.recv_list = rfl; cr_sdp.close_list = cfl; if ( cr_sdp.initialized ) { return; } cr_sdp.initialized = 1; crDebug("Initializing SDP"); cr_sdp.num_conns = 0; cr_sdp.conns = NULL; cr_sdp.server_sock = -1; #ifdef CHROMIUM_THREADSAFE crInitMutex(&cr_sdp.mutex); crInitMutex(&cr_sdp.recvmutex); #endif cr_sdp.bufpool = crBufferPoolInit(16); }
bool crVBoxHGSMIInit(CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu) { /* static */ int bHasHGSMI = -1; /* do it for all connections */ (void) mtu; if (bHasHGSMI < 0) { int rc; VBOXCRHGSMI_CALLBACKS Callbacks; Callbacks.pfnClientCreate = _crVBoxHGSMIClientCreate; Callbacks.pfnClientDestroy = _crVBoxHGSMIClientDestroy; rc = VBoxCrHgsmiInit(&Callbacks); AssertRC(rc); if (RT_SUCCESS(rc)) bHasHGSMI = 1; else bHasHGSMI = 0; } Assert(bHasHGSMI); if (!bHasHGSMI) { #ifdef DEBUG_misha AssertRelease(0); #endif return false; } g_crvboxhgsmi.recv_list = rfl; g_crvboxhgsmi.close_list = cfl; if (g_crvboxhgsmi.initialized) { return true; } g_crvboxhgsmi.initialized = 1; g_crvboxhgsmi.num_conns = 0; g_crvboxhgsmi.conns = NULL; g_crvboxhgsmi.mempool = crBufferPoolInit(16); /* Can't open VBox guest driver here, because it gets called for host side as well */ /*@todo as we have 2 dll versions, can do it now.*/ #ifdef RT_OS_WINDOWS g_crvboxhgsmi.hGuestDrv = INVALID_HANDLE_VALUE; #else g_crvboxhgsmi.iGuestDrv = INVALID_HANDLE_VALUE; #endif #ifdef CHROMIUM_THREADSAFE crInitMutex(&g_crvboxhgsmi.mutex); crInitMutex(&g_crvboxhgsmi.recvmutex); #endif return true; }
static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( crThreadID() ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; packspuCreateFunctions(); crStateInit(); return &pack_functions; }
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; }
static SPUFunctions *feedbackSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { (void) context_id; (void) num_contexts; #ifdef CHROMIUM_THREADSAFE crInitMutex(&feedback_spu.mutex); #endif feedback_spu.id = id; feedback_spu.has_child = 0; if (child) { crSPUInitDispatchTable( &(feedback_spu.child) ); crSPUCopyDispatchTable( &(feedback_spu.child), &(child->dispatch_table) ); feedback_spu.has_child = 1; } crSPUInitDispatchTable( &(feedback_spu.super) ); crSPUCopyDispatchTable( &(feedback_spu.super), &(self->superSPU->dispatch_table) ); feedbackspuGatherConfiguration(); /* create/init default state tracker */ crStateInit(); feedback_spu.defaultctx = crStateCreateContext(NULL, 0, NULL); crStateSetCurrent(feedback_spu.defaultctx); feedback_spu.numContexts = 0; crMemZero(feedback_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo)); return &feedback_functions; }
/** * 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) */ CRConnection * crNetConnectToServer( const char *server, unsigned short default_port, int mtu) { char hostname[4096], protocol[4096]; unsigned short port; CRConnection *conn; crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d )", server, default_port, mtu ); 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 ); } crDebug( "Connecting to %s on port %d, with protocol %s", hostname, port, protocol ); 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->endianness = crDetermineEndianness(); #ifdef CHROMIUM_THREADSAFE crInitMutex(&conn->messageList.lock); crInitCondition(&conn->messageList.nonEmpty); #endif /* now, just dispatch to the appropriate protocol's initialization functions. */ InitConnection(conn, protocol, mtu); if (!crNetConnect( conn )) { crDebug("crNetConnectToServer() failed, freeing the connection"); crFree( conn ); return NULL; } crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap ); #ifndef NDEBUG crNetDumpConnectionInfo(conn); #endif return conn; }
/** * Simple logging. This will be called by either thread whenever an * interesting event occurs. */ void vncspuLog(int threadNum, const char *msg, int i) { #if SIMPLE_LOGGING static FILE *logFile = NULL; char tb[32]; int k; struct timeval tv; if (!logFile) { /* one time init */ logFile = fopen("/tmp/vncspu.log", "w"); crInitMutex(&vnc_spu.logLock); } crLockMutex(&vnc_spu.logLock); gettimeofday(&tv, NULL); tv.tv_sec = tv.tv_sec % 10; sprintf(tb, "%2u.%06u ", (unsigned) tv.tv_sec, (unsigned) tv.tv_usec); fputs(tb, logFile); for (k = 0; k < threadNum; k++) fputs(" ", logFile); fprintf(logFile, msg, i); fputs("\n", logFile); crUnlockMutex(&vnc_spu.logLock); #endif }
void crInitMessageList(CRMessageList *list) { list->head = list->tail = NULL; list->numMessages = 0; #ifdef CHROMIUM_THREADSAFE crInitMutex(&list->lock); crInitCondition(&list->nonEmpty); #endif }
static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif #ifdef CHROMIUM_THREADSAFE crInitTSD(&_PackerTSD); crInitTSD(&_PackTSD); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) pack_spu.bIsWDDMCrHgsmi = isVBoxWDDMCrHgsmi(); #endif #ifdef VBOX_WITH_CRPACKSPU_DUMPER memset(&pack_spu.Dumper, 0, sizeof (pack_spu.Dumper)); #endif if (!CRPACKSPU_IS_WDDM_CRHGSMI()) { /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) NULL #endif ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; } packspuCreateFunctions(); crStateInit(); return &pack_functions; }
CRPackContext *crPackNewContext(void) { CRPackContext *pc = crCalloc(sizeof(CRPackContext)); if (!pc) return NULL; crInitMutex(&pc->mutex); pc->u32CmdBlockState = 0; pc->Flush = NULL; pc->SendHuge = NULL; pc->updateBBOX = 0; return pc; }
CRHashTable *crAllocHashtable( void ) { int i; CRHashTable *hash = (CRHashTable *) crCalloc( sizeof( CRHashTable )) ; hash->num_elements = 0; for (i = 0 ; i < CR_NUM_BUCKETS ; i++) { hash->buckets[i] = NULL; } hash->idPool = crAllocHashIdPool(); #ifdef CHROMIUM_THREADSAFE crInitMutex(&hash->mutex); #endif return hash; }
static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) pack_spu.bRunningUnderWDDM = !!GetModuleHandle(VBOX_MODNAME_DISPD3D); #endif if (!CRPACKSPU_IS_WDDM_CRHGSMI()) { /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) NULL #endif ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; } packspuCreateFunctions(); crStateInit(); return &pack_functions; }
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; }
static SPUFunctions *hiddenlineSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { (void) context_id; (void) num_contexts; #ifdef CHROMIUM_THREADSAFE crDebug("Hiddenline SPU: thread-safe"); #endif hiddenline_spu.id = id; hiddenline_spu.has_child = 0; if (child) { crSPUInitDispatchTable( &(hiddenline_spu.child) ); crSPUCopyDispatchTable( &(hiddenline_spu.child), &(child->dispatch_table) ); hiddenline_spu.has_child = 1; } crSPUInitDispatchTable( &(hiddenline_spu.super) ); crSPUCopyDispatchTable( &(hiddenline_spu.super), &(self->superSPU->dispatch_table) ); hiddenlinespuGatherConfiguration( child ); /* We need to track state so that the packer can deal with pixel data */ crStateInit(); hiddenlinespuCreateFunctions(); hiddenline_spu.contextTable = crAllocHashtable(); #ifdef CHROMIUM_THREADSAFE crInitTSD(&_HiddenlineTSD); #else hiddenline_spu.currentContext = NULL; #endif crInitMutex(&(hiddenline_spu.mutex)); return &hiddenline_functions; }
static SPUFunctions *arraySPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { (void) context_id; (void) num_contexts; #ifdef CHROMIUM_THREADSAFE crInitMutex(&_ArrayMutex); #endif array_spu.id = id; array_spu.has_child = 0; if (child) { crSPUInitDispatchTable( &(array_spu.child) ); crSPUCopyDispatchTable( &(array_spu.child), &(child->dispatch_table) ); array_spu.has_child = 1; } crSPUInitDispatchTable( &(array_spu.super) ); crSPUCopyDispatchTable( &(array_spu.super), &(self->superSPU->dispatch_table) ); arrayspuSetVBoxConfiguration(); crStateInit(); /*@todo seems default context ain't needed at all*/ array_spu.defaultctx = crStateCreateContext( NULL, 0, NULL ); #ifdef CR_ARB_vertex_buffer_object array_spu.defaultctx->bufferobject.retainBufferData = GL_TRUE; #endif /* we call SetCurrent instead of MakeCurrent as the differencer * isn't setup yet anyway */ crStateSetCurrent( array_spu.defaultctx ); array_spu.numContexts = 0; crMemZero(array_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo)); return &array_functions; }
void crFileInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu ) { (void) mtu; cr_file.recv_list = rfl; cr_file.close_list = cfl; if (cr_file.initialized) { return; } cr_file.num_conns = 0; cr_file.conns = NULL; #ifdef CHROMIUM_THREADSAFE crInitMutex(&cr_file.mutex); #endif cr_file.bufpool = crBufferPoolInit(16); cr_file.initialized = 1; }
/** * Start the thread which handles all the RFB serving. */ void vncspuStartServerThread(void) { CRthread thread; /* init locks and condition vars */ crInitMutex(&vnc_spu.lock); crInitCondition(&vnc_spu.cond); /* spawn the thread */ (void) crCreateThread(&thread, 0, vnc_main, NULL); if (vnc_spu.server_port == -1) { /* Wait until the child thread has successfully allocated a port * for clients to connect to. */ crLockMutex(&vnc_spu.lock); while (vnc_spu.server_port == -1) { crWaitCondition(&vnc_spu.cond, &vnc_spu.lock); } crUnlockMutex(&vnc_spu.lock); } crDebug("VNC SPU: VNC Server port: %d", vnc_spu.server_port); /* * OK, we know our VNC server's port now. Use the libVncExt library * call to tell the VNC server to send the ChromiumStart message to * all attached viewers. Upon getting that message the viewers will * connect to the VNC server thread which we just started. */ CRASSERT(vnc_spu.server_port != -1); #if defined(HAVE_VNC_EXT) vncspuSendVncStartUpMsg(vnc_spu.server_port); #endif }
/** * This function creates and initializes a new display list * manager. It returns a pointer to the manager, or NULL in * the case of insufficient memory. The dispatch table pointer * is passed in to allow the utilities to muck with the table * to gain functional control when GL calls are made. */ CRDLM DLM_APIENTRY *crDLMNewDLM(unsigned int userConfigSize, const CRDLMConfig *userConfig) { CRDLM *dlm; /* This is the default configuration. We'll overwrite it later * with user-supplied configuration information. */ CRDLMConfig config = { CRDLM_DEFAULT_BUFFERSIZE, }; dlm = crAlloc(sizeof(*dlm)); if (!dlm) { return NULL; } /* Start off by initializing all entries that require further * memory allocation, so we can free up all the memory if there's * a problem. */ if (!(dlm->displayLists = crAllocHashtable())) { crFree(dlm); return NULL; } /* The creator counts as the first user. */ dlm->userCount = 1; #ifdef CHROMIUM_THREADSAFE /* This mutex ensures that only one thread is changing the displayLists * hash at a time. Note that we may also need a mutex to guarantee that * the hash is not changed by one thread while another thread is * traversing it; this issue has not yet been resolved. */ crInitMutex(&(dlm->dlMutex)); /* Although the thread-specific data (TSD) functions will initialize * the thread key themselves when needed, those functions do not allow * us to specify a thread destructor. Since a thread could potentially * exit with considerable memory allocated (e.g. if a thread exits * after it has issued NewList but before EndList, and while there * are considerable content buffers allocated), I do the initialization * myself, in order to be able to reclaim those resources if a thread * exits. */ crInitTSDF(&(dlm->tsdKey), threadDestructor); crInitTSD(&CRDLMTSDKey); #endif /* Copy over any appropriate configuration values */ if (userConfig != NULL) { /* Copy over as much configuration information as is provided. * Note that if the CRDLMConfig structure strictly grows, this * allows forward compatability - routines compiled with * older versions of the structure will only initialize that * section of the structure that they know about. */ crMemcpy((void *)&config, (void *) userConfig, MIN(userConfigSize, sizeof(config))); } dlm->bufferSize = config.bufferSize; /* Return the pointer to the newly-allocated display list manager */ return dlm; }
/** * Init variables in the stub structure, install signal handler. */ static void stubInitVars(void) { WindowInfo *defaultWin; #ifdef CHROMIUM_THREADSAFE crInitMutex(&stub.mutex); #endif /* At the very least we want CR_RGB_BIT. */ stub.haveNativeOpenGL = GL_FALSE; stub.spu = NULL; stub.appDrawCursor = 0; stub.minChromiumWindowWidth = 0; stub.minChromiumWindowHeight = 0; stub.maxChromiumWindowWidth = 0; stub.maxChromiumWindowHeight = 0; stub.matchChromiumWindowCount = 0; stub.matchChromiumWindowID = NULL; stub.matchWindowTitle = NULL; stub.ignoreFreeglutMenus = 0; stub.threadSafe = GL_FALSE; stub.trackWindowSize = 0; stub.trackWindowPos = 0; stub.trackWindowVisibility = 0; stub.trackWindowVisibleRgn = 0; stub.mothershipPID = 0; stub.spu_dir = NULL; stub.freeContextNumber = MAGIC_CONTEXT_BASE; stub.contextTable = crAllocHashtable(); #ifndef RT_OS_WINDOWS # ifdef CHROMIUM_THREADSAFE if (!g_stubIsCurrentContextTSDInited) { crInitTSDF(&g_stubCurrentContextTSD, stubThreadTlsDtor); g_stubIsCurrentContextTSDInited = true; } # endif #endif stubSetCurrentContext(NULL); stub.windowTable = crAllocHashtable(); #ifdef CR_NEWWINTRACK stub.bShutdownSyncThread = false; stub.hSyncThread = NIL_RTTHREAD; #endif defaultWin = (WindowInfo *) crCalloc(sizeof(WindowInfo)); defaultWin->type = CHROMIUM; defaultWin->spuWindow = 0; /* window 0 always exists */ #ifdef WINDOWS defaultWin->hVisibleRegion = INVALID_HANDLE_VALUE; #elif defined(GLX) defaultWin->pVisibleRegions = NULL; defaultWin->cVisibleRegions = 0; #endif crHashtableAdd(stub.windowTable, 0, defaultWin); #if 1 atexit(stubExitHandler); signal(SIGTERM, stubSignalHandler); signal(SIGINT, stubSignalHandler); #ifndef WINDOWS signal(SIGPIPE, SIG_IGN); /* the networking code should catch this */ #endif #else (void) stubExitHandler; (void) stubSignalHandler; #endif }
/* Windows crap */ BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved) { (void) lpvReserved; switch (fdwReason) { case DLL_PROCESS_ATTACH: { CRNetServer ns; #ifdef CHROMIUM_THREADSAFE crInitTSD(&g_stubCurrentContextTSD); #endif crInitMutex(&stub_init_mutex); #ifdef VDBG_VEHANDLER vboxVDbgVEHandlerRegister(); #endif crNetInit(NULL, NULL); ns.name = "vboxhgcm://host:0"; ns.buffer_size = 1024; crNetServerConnect(&ns #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , NULL #endif ); if (!ns.conn) { crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load."); #ifdef VDBG_VEHANDLER vboxVDbgVEHandlerUnregister(); #endif return FALSE; } else crNetFreeConnection(ns.conn); break; } case DLL_PROCESS_DETACH: { /* do exactly the same thing as for DLL_THREAD_DETACH since * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */ stubSetCurrentContext(NULL); if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxDetachThread(); } stubSPUSafeTearDown(); #ifdef CHROMIUM_THREADSAFE crFreeTSD(&g_stubCurrentContextTSD); #endif #ifdef VDBG_VEHANDLER vboxVDbgVEHandlerUnregister(); #endif break; } case DLL_THREAD_ATTACH: { if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxAttachThread(); } break; } case DLL_THREAD_DETACH: { stubSetCurrentContext(NULL); if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxDetachThread(); } break; } default: break; } return TRUE; }
/** * Start the ball rolling. give functions to handle incoming traffic * (usually placing blocks on a queue), and a handler for dropped * connections. */ void crNetInit( CRNetReceiveFunc recvFunc, CRNetCloseFunc closeFunc ) { CRNetReceiveFuncList *rfl; CRNetCloseFuncList *cfl; if ( cr_net.initialized ) { /*crDebug( "Networking already initialized!" );*/ } else { #ifdef WINDOWS /* @todo: do we actually need that WSA stuff with VBox at all? */ WORD wVersionRequested = MAKEWORD(2, 0); WSADATA wsaData; int err; err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) crError("Couldn't initialize sockets on WINDOWS"); //reinit hostname for debug messages as it's incorrect before WSAStartup gets called __getHostInfo(); #endif cr_net.use_gm = 0; cr_net.use_udp = 0; cr_net.use_tcpip = 0; cr_net.use_sdp = 0; cr_net.use_tcscomm = 0; cr_net.use_teac = 0; cr_net.use_file = 0; cr_net.use_hgcm = 0; cr_net.num_clients = 0; #ifdef CHROMIUM_THREADSAFE crInitMutex(&cr_net.mutex); #endif cr_net.initialized = 1; cr_net.recv_list = NULL; cr_net.close_list = NULL; } if (recvFunc != NULL) { /* check if function is already in the list */ for (rfl = cr_net.recv_list ; rfl ; rfl = rfl->next ) { if (rfl->recv == recvFunc) { /* we've already seen this function -- do nothing */ break; } } /* not in list, so insert at the head */ if (!rfl) { rfl = (CRNetReceiveFuncList *) crAlloc( sizeof (*rfl )); rfl->recv = recvFunc; rfl->next = cr_net.recv_list; cr_net.recv_list = rfl; } } if (closeFunc != NULL) { /* check if function is already in the list */ for (cfl = cr_net.close_list ; cfl ; cfl = cfl->next ) { if (cfl->close == closeFunc) { /* we've already seen this function -- do nothing */ break; } } /* not in list, so insert at the head */ if (!cfl) { cfl = (CRNetCloseFuncList *) crAlloc( sizeof (*cfl )); cfl->close = closeFunc; cfl->next = cr_net.close_list; cr_net.close_list = cfl; } } }
/** * 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 ) { 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; #ifdef CHROMIUM_THREADSAFE crInitMutex(&conn->messageList.lock); crInitCondition(&conn->messageList.nonEmpty); #endif /* now, just dispatch to the appropriate protocol's initialization functions. */ InitConnection(conn, protocol, mtu); if (!crNetConnect( conn )) { crDebug("crNetConnectToServer() failed, freeing the connection"); crFree( conn ); return NULL; } crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap ); return conn; }
/** * Start the ball rolling. give functions to handle incoming traffic * (usually placing blocks on a queue), and a handler for dropped * connections. */ void crNetInit( CRNetReceiveFunc recvFunc, CRNetCloseFunc closeFunc ) { CRNetReceiveFuncList *rfl; CRNetCloseFuncList *cfl; if ( cr_net.initialized ) { /*crDebug( "Networking already initialized!" );*/ } else { cr_net.use_gm = 0; cr_net.use_udp = 0; cr_net.use_tcpip = 0; cr_net.use_sdp = 0; cr_net.use_tcscomm = 0; cr_net.use_teac = 0; cr_net.use_file = 0; cr_net.num_clients = 0; #ifdef CHROMIUM_THREADSAFE crInitMutex(&cr_net.mutex); #endif cr_net.initialized = 1; cr_net.recv_list = NULL; cr_net.close_list = NULL; } if (recvFunc != NULL) { /* check if function is already in the list */ for (rfl = cr_net.recv_list ; rfl ; rfl = rfl->next ) { if (rfl->recv == recvFunc) { /* we've already seen this function -- do nothing */ break; } } /* not in list, so insert at the head */ if (!rfl) { rfl = (CRNetReceiveFuncList *) crAlloc( sizeof (*rfl )); rfl->recv = recvFunc; rfl->next = cr_net.recv_list; cr_net.recv_list = rfl; } } if (closeFunc != NULL) { /* check if function is already in the list */ for (cfl = cr_net.close_list ; cfl ; cfl = cfl->next ) { if (cfl->close == closeFunc) { /* we've already seen this function -- do nothing */ break; } } /* not in list, so insert at the head */ if (!cfl) { cfl = (CRNetCloseFuncList *) crAlloc( sizeof (*cfl )); cfl->close = closeFunc; cfl->next = cr_net.close_list; cr_net.close_list = cfl; } } }
/* Windows crap */ BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved) { (void) lpvReserved; switch (fdwReason) { case DLL_PROCESS_ATTACH: { CRNetServer ns; const char * env; #if defined(DEBUG_misha) HMODULE hCrUtil; char aName[MAX_PATH]; GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName)); crDbgCmdSymLoadPrint(aName, hDLLInst); hCrUtil = GetModuleHandleA("VBoxOGLcrutil.dll"); Assert(hCrUtil); crDbgCmdSymLoadPrint("VBoxOGLcrutil.dll", hCrUtil); #endif #ifdef CHROMIUM_THREADSAFE crInitTSD(&g_stubCurrentContextTSD); #endif crInitMutex(&stub_init_mutex); #ifdef VDBG_VEHANDLER env = crGetenv("CR_DBG_VEH_ENABLE"); g_VBoxVehEnable = crStrParseI32(env, # ifdef DEBUG_misha 1 # else 0 # endif ); if (g_VBoxVehEnable) { char procName[1024]; size_t cProcName; size_t cChars; env = crGetenv("CR_DBG_VEH_FLAGS"); g_VBoxVehFlags = crStrParseI32(env, 0 # ifdef DEBUG_misha | VBOXVEH_F_BREAK # else | VBOXVEH_F_DUMP # endif ); env = crGetenv("CR_DBG_VEH_DUMP_DIR"); if (!env) env = VBOXMD_DUMP_DIR_DEFAULT; g_cVBoxMdFilePrefixLen = strlen(env); if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) <= g_cVBoxMdFilePrefixLen + 26 + (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR)) { g_cVBoxMdFilePrefixLen = 0; env = ""; } mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix, g_cVBoxMdFilePrefixLen + 1, env, _TRUNCATE); Assert(cChars == g_cVBoxMdFilePrefixLen + 1); g_cVBoxMdFilePrefixLen = cChars - 1; if (g_cVBoxMdFilePrefixLen && g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen - 1] != L'\\') g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'\\'; memcpy(g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, VBOXMD_DUMP_NAME_PREFIX_W, sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)); g_cVBoxMdFilePrefixLen += (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR); crGetProcName(procName, RT_ELEMENTS(procName)); cProcName = strlen(procName); if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) > g_cVBoxMdFilePrefixLen + cProcName + 1 + 26) { mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, cProcName + 1, procName, _TRUNCATE); Assert(cChars == cProcName + 1); g_cVBoxMdFilePrefixLen += cChars - 1; g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'_'; } /* sanity */ g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen] = L'\0'; env = crGetenv("CR_DBG_VEH_DUMP_TYPE"); g_enmVBoxMdDumpType = crStrParseI32(env, MiniDumpNormal | MiniDumpWithDataSegs | MiniDumpWithFullMemory | MiniDumpWithHandleData //// | MiniDumpFilterMemory //// | MiniDumpScanMemory // | MiniDumpWithUnloadedModules //// | MiniDumpWithIndirectlyReferencedMemory //// | MiniDumpFilterModulePaths // | MiniDumpWithProcessThreadData // | MiniDumpWithPrivateReadWriteMemory //// | MiniDumpWithoutOptionalData // | MiniDumpWithFullMemoryInfo // | MiniDumpWithThreadInfo // | MiniDumpWithCodeSegs // | MiniDumpWithFullAuxiliaryState // | MiniDumpWithPrivateWriteCopyMemory // | MiniDumpIgnoreInaccessibleMemory // | MiniDumpWithTokenInformation //// | MiniDumpWithModuleHeaders //// | MiniDumpFilterTriage ); vboxVDbgVEHandlerRegister(); } #endif crNetInit(NULL, NULL); ns.name = "vboxhgcm://host:0"; ns.buffer_size = 1024; crNetServerConnect(&ns #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) , NULL #endif ); if (!ns.conn) { crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load."); #ifdef VDBG_VEHANDLER if (g_VBoxVehEnable) vboxVDbgVEHandlerUnregister(); #endif return FALSE; } else { crNetFreeConnection(ns.conn); } #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) VBoxCrHgsmiInit(); #endif break; } case DLL_PROCESS_DETACH: { /* do exactly the same thing as for DLL_THREAD_DETACH since * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */ stubSetCurrentContext(NULL); if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxDetachThread(); } #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) VBoxCrHgsmiTerm(); #endif stubSPUSafeTearDown(); #ifdef CHROMIUM_THREADSAFE crFreeTSD(&g_stubCurrentContextTSD); #endif #ifdef VDBG_VEHANDLER if (g_VBoxVehEnable) vboxVDbgVEHandlerUnregister(); #endif break; } case DLL_THREAD_ATTACH: { if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxAttachThread(); } break; } case DLL_THREAD_DETACH: { stubSetCurrentContext(NULL); if (stub_initialized) { CRASSERT(stub.spu); stub.spu->dispatch_table.VBoxDetachThread(); } break; } default: break; } return TRUE; }
static SPUFunctions * tilesortSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread0 = &(tilesort_spu.thread[0]); (void) context_id; (void) num_contexts; (void) child; (void) self; #if DEBUG_FP_EXCEPTIONS { fpu_control_t mask; _FPU_GETCW(mask); mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM); _FPU_SETCW(mask); } #endif crRandSeed(id); crMemZero( &tilesort_spu, sizeof(TileSortSPU) ); #ifdef CHROMIUM_THREADSAFE crInitTSD(&_ThreadTSD); crSetTSD(&_ThreadTSD, thread0); crInitMutex(&_TileSortMutex); #endif thread0->state_server_index = -1; /* one-time init for thread */ tilesortspuInitEvaluators(); /* Init window, context hash tables */ tilesort_spu.windowTable = crAllocHashtable(); tilesort_spu.contextTable = crAllocHashtable(); tilesort_spu.listTable = crAllocHashtable(); tilesort_spu.id = id; tilesort_spu.glassesType = RED_BLUE; tilesortspuSetAnaglyphMask(&tilesort_spu); tilesortspuGatherConfiguration( child ); tilesortspuConnectToServers(); /* set up thread0's server connection */ tilesort_spu.geom_buffer_size = tilesort_spu.buffer_size; /* geom_buffer_mtu must fit in data's part of our buffers */ tilesort_spu.geom_buffer_mtu = crPackMaxData(tilesort_spu.buffer_size) /* 24 is the size of the bounds info packet * END_FLUFF is the size of data of the extra End opcode if needed * 4 since BoundsInfo opcode may take a whole 4 bytes * and 4 to let room for extra End's opcode, if needed */ - (24+END_FLUFF+4+4); /* the geometry must also fit in the mtu */ if (tilesort_spu.geom_buffer_mtu > tilesort_spu.MTU - sizeof(CRMessageOpcodes) - (24+END_FLUFF+4+4)) tilesort_spu.geom_buffer_mtu = tilesort_spu.MTU - sizeof(CRMessageOpcodes) - (24+END_FLUFF+4+4); tilesort_spu.swap = thread0->netServer[0].conn->swap; tilesortspuInitThreadPacking( thread0 ); tilesortspuCreateFunctions(); crStateInit(); tilesortspuCreateDiffAPI(); /* special dispatch tables for display lists */ if (tilesort_spu.listTrack || tilesort_spu.lazySendDLists) { crMemZero((void *)&tilesort_spu.packerDispatch, sizeof tilesort_spu.packerDispatch); crSPUInitDispatchTable(&tilesort_spu.packerDispatch); tilesortspuLoadPackTable(&tilesort_spu.packerDispatch); crSPUInitDispatchTable(&tilesort_spu.stateDispatch); tilesortspuLoadStateTable(&tilesort_spu.stateDispatch); } if (tilesort_spu.useDMX) { /* load OpenGL */ int n; crDebug("Tilesort SPU: Using DMX"); n = crLoadOpenGL( &tilesort_spu.ws, NULL); if (!n) { crWarning("Tilesort SPU: Unable to load OpenGL, disabling DMX"); tilesort_spu.useDMX = 0; } } else { crDebug("Tilesort SPU: Not using DMX"); } crDebug("Tilesort SPU: ---------- End of Init -------------"); return &tilesort_functions; }