void crServerAddToRunQueue( CRClient *client ) { RunQueue *q = (RunQueue *) crAlloc( sizeof( *q ) ); #ifdef VBOX_WITH_CRHGSMI client->conn->pClient = client; CRVBOXHGSMI_CMDDATA_CLEANUP(&client->conn->CmdData); #endif /* give this client a unique number if needed */ if (!client->number) { client->number = client->conn->u32ClientID; } crDebug("Adding client %p to the run queue", client); if (FindClientInQueue(client)) { crError("CRServer: client %p already in the queue!", client); } q->client = client; q->blocked = 0; if (!cr_server.run_queue) { /* adding to empty queue */ cr_server.run_queue = q; q->next = q; q->prev = q; } else { /* insert in doubly-linked list */ q->next = cr_server.run_queue->next; cr_server.run_queue->next->prev = q; q->prev = cr_server.run_queue; cr_server.run_queue->next = q; } }
void glStubAddToRunQueue( CRClient *client ) { static int clientId = 1; RunQueue *q = (RunQueue *) crAlloc( sizeof( *q ) ); /* give this client a unique number if needed */ if (!client->number) { client->number = clientId++; } crDebug("Adding client %p to the run queue", client); if (FindClientInQueue(client)) { crError("GLStub: client %p already in the queue!", client); } q->client = client; q->blocked = 0; if (!cr_server.run_queue) { /* adding to empty queue */ cr_server.run_queue = q; q->next = q; q->prev = q; } else { /* insert in doubly-linked list */ q->next = cr_server.run_queue->next; cr_server.run_queue->next->prev = q; q->prev = cr_server.run_queue; cr_server.run_queue->next = q; } }
static void glStubDeleteClient( CRClient *client ) { int i, j; crDebug("Deleting client %p (%d msgs left)", client, crNetNumMessages(client->conn)); #if 0 if (crNetNumMessages(client->conn) > 0) { crDebug("Delay destroying client: message still pending"); return; } #endif if (!FindClientInQueue(client)) { /* this should never happen */ crError("GLStub: client %p not found in the queue!", client); } /* remove from clients[] array */ for (i = 0; i < cr_server.numClients; i++) { if (cr_server.clients[i] == client) { /* found it */ for (j = i; j < cr_server.numClients - 1; j++) cr_server.clients[j] = cr_server.clients[j + 1]; cr_server.numClients--; break; } } /* remove from the run queue */ if (cr_server.run_queue) { RunQueue *q = cr_server.run_queue; RunQueue *qStart = cr_server.run_queue; do { if (q->client == client) { /* this test seems a bit excessive */ if ((q->next == q->prev) && (q->next == q) && (cr_server.run_queue == q)) { /* We're removing/deleting the only client */ CRASSERT(cr_server.numClients == 0); crFree(q); cr_server.run_queue = NULL; cr_server.curClient = NULL; crDebug("Last client deleted - empty run queue."); } else { /* remove from doubly linked list and free the node */ if (cr_server.curClient == q->client) cr_server.curClient = NULL; if (cr_server.run_queue == q) cr_server.run_queue = q->next; q->prev->next = q->next; q->next->prev = q->prev; crFree(q); } break; } q = q->next; } while (q != qStart); } crNetFreeConnection(client->conn); crFree(client); }
void crServerDeleteClient( CRClient *client ) { int i, j; int cleanup=1; crDebug("Deleting client %p (%d msgs left)", client, crNetNumMessages(client->conn)); #if 0 if (crNetNumMessages(client->conn) > 0) { crDebug("Delay destroying client: message still pending"); return; } #endif if (!FindClientInQueue(client)) { /* this should never happen */ crError("CRServer: client %p not found in the queue!", client); } /* remove from clients[] array */ for (i = 0; i < cr_server.numClients; i++) { if (cr_server.clients[i] == client) { /* found it */ for (j = i; j < cr_server.numClients - 1; j++) cr_server.clients[j] = cr_server.clients[j + 1]; cr_server.numClients--; break; } } /* check if there're any other guest threads in same process */ for (i=0; i < cr_server.numClients; i++) { if (cr_server.clients[i]->pid==client->pid) { cleanup=0; break; } } if (cleanup) { crServerCleanupClient(client); } /* remove from the run queue */ if (cr_server.run_queue) { RunQueue *q = cr_server.run_queue; RunQueue *qStart = cr_server.run_queue; do { if (q->client == client) { /* this test seems a bit excessive */ if ((q->next == q->prev) && (q->next == q) && (cr_server.run_queue == q)) { /* We're removing/deleting the only client */ CRASSERT(cr_server.numClients == 0); crFree(q); cr_server.run_queue = NULL; cr_server.curClient = NULL; crDebug("Last client deleted - empty run queue."); } else { /* remove from doubly linked list and free the node */ if (cr_server.curClient == q->client) cr_server.curClient = NULL; if (cr_server.run_queue == q) cr_server.run_queue = q->next; q->prev->next = q->next; q->next->prev = q->prev; crFree(q); } break; } q = q->next; } while (q != qStart); } crNetFreeConnection(client->conn); client->conn = NULL; if (cleanup) { crServerCleanupByPID(client->pid); crFree(client); } else { CRClientNode *pNode = (CRClientNode *)crAlloc(sizeof(CRClientNode)); if (!pNode) { crWarning("Not enough memory, forcing client cleanup"); crServerCleanupClient(client); crServerCleanupByPID(client->pid); crFree(client); return; } pNode->pClient = client; pNode->prev = NULL; pNode->next = cr_server.pCleanupClient; cr_server.pCleanupClient = pNode; } }
void crServerDeleteClient( CRClient *client ) { int i, j; int cleanup=1; crDebug("Deleting client %p (%d msgs left)", client, crNetNumMessages(client->conn)); #if 0 if (crNetNumMessages(client->conn) > 0) { crDebug("Delay destroying client: message still pending"); return; } #endif if (!FindClientInQueue(client)) { /* this should never happen */ crError("CRServer: client %p not found in the queue!", client); } /* remove from clients[] array */ for (i = 0; i < cr_server.numClients; i++) { if (cr_server.clients[i] == client) { /* found it */ for (j = i; j < cr_server.numClients - 1; j++) cr_server.clients[j] = cr_server.clients[j + 1]; cr_server.numClients--; break; } } /* check if there're any other guest threads in same process */ for (i=0; i < cr_server.numClients; i++) { if (cr_server.clients[i]->pid==client->pid) { cleanup=0; break; } } if (cleanup) { crServerCleanupClient(client); } /* remove from the run queue */ if (cr_server.run_queue) { RunQueue *q = cr_server.run_queue; RunQueue *qStart = cr_server.run_queue; do { if (q->client == client) { /* this test seems a bit excessive */ if ((q->next == q->prev) && (q->next == q) && (cr_server.run_queue == q)) { /* We're removing/deleting the only client */ CRASSERT(cr_server.numClients == 0); crFree(q); cr_server.run_queue = NULL; cr_server.curClient = NULL; crDebug("Last client deleted - empty run queue."); } else { /* remove from doubly linked list and free the node */ if (cr_server.curClient == q->client) cr_server.curClient = NULL; if (cr_server.run_queue == q) cr_server.run_queue = q->next; q->prev->next = q->next; q->next->prev = q->prev; crFree(q); } break; } q = q->next; } while (q != qStart); } crNetFreeConnection(client->conn); client->conn = NULL; if (cleanup) { crServerCleanupByPID(client->pid); crFree(client); } else { CRClientNode *pNode = (CRClientNode *)crAlloc(sizeof(CRClientNode)); if (!pNode) { crWarning("Not enough memory, forcing client cleanup"); crServerCleanupClient(client); crServerCleanupByPID(client->pid); crFree(client); return; } pNode->pClient = client; pNode->prev = NULL; pNode->next = cr_server.pCleanupClient; cr_server.pCleanupClient = pNode; } if (!cr_server.numClients) { /* if no clients, the guest driver may be unloaded, * and thus the visible regions situation might not be under control anymore, * so cleanup the 3D framebuffer data here * @todo: what really should happen is that guest driver on unload * posts some request to host that would copy the current framebuffer 3D data to the 2D buffer * (i.e. to the memory used by the standard IFramebuffer API) */ HCR_FRAMEBUFFER hFb; for (hFb = CrPMgrFbGetFirstEnabled(); hFb; hFb = CrPMgrFbGetNextEnabled(hFb)) { int rc = CrFbUpdateBegin(hFb); if (RT_SUCCESS(rc)) { CrFbRegionsClear(hFb); CrFbUpdateEnd(hFb); } else WARN(("CrFbUpdateBegin failed %d", rc)); } } }