VirtualBox

Ignore:
Timestamp:
Nov 11, 2010 1:03:17 PM (14 years ago)
Author:
vboxsync
Message:

crOpenGL/wddm: more multithreading fixes, vista expirience index works now

Location:
trunk/src/VBox/HostServices/SharedOpenGL
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r33540 r33988  
    463463        }
    464464
     465        case SHCRGL_GUEST_FN_SET_PID:
     466        {
     467            Log(("svcCall: SHCRGL_GUEST_FN_SET_PID\n"));
     468
     469            /* Verify parameter count and types. */
     470            if (cParms != SHCRGL_CPARMS_SET_PID)
     471            {
     472                rc = VERR_INVALID_PARAMETER;
     473            }
     474            else
     475            if (paParms[0].type != VBOX_HGCM_SVC_PARM_64BIT)
     476            {
     477                rc = VERR_INVALID_PARAMETER;
     478            }
     479            else
     480            {
     481                /* Fetch parameters. */
     482                uint64_t pid    = paParms[0].u.uint64;
     483
     484                /* Execute the function. */
     485                rc = crVBoxServerClientSetPID(u32ClientID, pid);
     486            }
     487
     488            break;
     489        }
     490
    465491        default:
    466492        {
     
    675701
    676702        case SHCRGL_GUEST_FN_SET_VERSION:
     703        {
     704            Assert(0);
     705            rc = VERR_NOT_IMPLEMENTED;
     706            break;
     707        }
     708
     709        case SHCRGL_GUEST_FN_SET_PID:
    677710        {
    678711            Assert(0);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c

    r33509 r33988  
    111111}
    112112
     113static int crServerRemoveClientContext(CRClient *pClient, GLint ctx)
     114{
     115    int pos;
     116
     117    for (pos = 0; pos < CR_MAX_CONTEXTS; ++pos)
     118    {
     119        if (pClient->contextList[pos] == ctx)
     120        {
     121            pClient->contextList[pos] = 0;
     122            return true;
     123        }
     124    }
     125
     126    return false;
     127}
     128
    113129void SERVER_DISPATCH_APIENTRY
    114130crServerDispatchDestroyContext( GLint ctx )
    115131{
    116132    CRContext *crCtx;
     133    int32_t client;
     134    CRClientNode *pNode;
     135    int found=false;
    117136
    118137    crCtx = (CRContext *) crHashtableSearch(cr_server.contextTable, ctx);
     
    130149    if (cr_server.curClient)
    131150    {
    132         int32_t pos;
    133 
    134151        /* If we delete our current context, default back to the null context */
    135152        if (cr_server.curClient->currentCtx == crCtx) {
     
    138155        }
    139156
    140         for (pos = 0; pos < CR_MAX_CONTEXTS; ++pos)
    141             if (cr_server.curClient->contextList[pos] == ctx)
    142             {
    143                 cr_server.curClient->contextList[pos] = 0;
    144                 break;
    145             }
     157        found = crServerRemoveClientContext(cr_server.curClient, ctx);
    146158
    147159        /*Some application call destroy context not in a thread where it was created...have do deal with it.*/
    148         if (CR_MAX_CONTEXTS==pos)
    149         {
    150             int32_t client;
    151 
     160        if (!found)
     161        {
    152162            for (client=0; client<cr_server.numClients; ++client)
    153163            {
     
    155165                    continue;
    156166
    157                 for (pos = 0; pos < CR_MAX_CONTEXTS; ++pos)
    158                     if (cr_server.clients[client]->contextList[pos] == ctx)
    159                     {
    160                         cr_server.clients[client]->contextList[pos] = 0;
    161                         break;
    162                     }
    163 
    164                 if (pos<CR_MAX_CONTEXTS)
    165                 {
    166                     if (cr_server.clients[client]->currentCtx == crCtx)
    167                     {
    168                         cr_server.clients[client]->currentContextNumber = -1;
    169                         cr_server.clients[client]->currentCtx = cr_server.DummyContext;
    170                     }
    171                     break;
    172                 }
     167                found = crServerRemoveClientContext(cr_server.clients[client], ctx);
     168
     169                if (found) break;
    173170            }
    174171        }
    175172
    176         CRASSERT(pos<CR_MAX_CONTEXTS);
     173        if (!found)
     174        {
     175            pNode=cr_server.pCleanupClient;
     176
     177            while (pNode && !found)
     178            {
     179                found = crServerRemoveClientContext(pNode->pClient, ctx);
     180                pNode = pNode->next;
     181            }
     182        }
     183
     184        CRASSERT(found);
     185    }
     186
     187    /*Make sure this context isn't active in other clients*/
     188    for (client=0; client<cr_server.numClients; ++client)
     189    {
     190        if (cr_server.clients[client]->currentCtx == crCtx)
     191        {
     192            cr_server.clients[client]->currentContextNumber = -1;
     193            cr_server.clients[client]->currentCtx = cr_server.DummyContext;
     194        }
     195    }
     196
     197    pNode=cr_server.pCleanupClient;
     198    while (pNode)
     199    {
     200        if (pNode->pClient->currentCtx == crCtx)
     201        {
     202            pNode->pClient->currentContextNumber = -1;
     203            pNode->pClient->currentCtx = cr_server.DummyContext;
     204        }
     205        pNode = pNode->next;
    177206    }
    178207}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r33540 r33988  
    7878{
    7979    GLint i;
     80    CRClientNode *pNode, *pNext;
    8081
    8182    /* avoid a race condition */
     
    119120    }
    120121    cr_server.numClients = 0;
     122
     123    pNode = cr_server.pCleanupClient;
     124    while (pNode)
     125    {
     126        pNext=pNode->next;
     127        crFree(pNode->pClient);
     128        crFree(pNode);
     129        pNode=pNext;
     130    }
     131    cr_server.pCleanupClient = NULL;
    121132
    122133#if 1
     
    289300    cr_server.bIsInLoadingState = GL_FALSE;
    290301    cr_server.bIsInSavingState  = GL_FALSE;
     302
     303    cr_server.pCleanupClient = NULL;
    291304
    292305    /*
     
    358371void crVBoxServerRemoveClient(uint32_t u32ClientID)
    359372{
    360     CRClient *pClient;
     373    CRClient *pClient=NULL;
    361374    int32_t i;
    362375
     
    368381            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
    369382        {
     383            pClient = cr_server.clients[i];
    370384            break;
    371385        }
    372386    }
    373     pClient = cr_server.clients[i];
    374     CRASSERT(pClient);
     387    //if (!pClient) return VERR_INVALID_PARAMETER;
     388    if (!pClient)
     389    {
     390        crWarning("Invalid client id %u passed to crVBoxServerRemoveClient", u32ClientID);
     391        return;
     392    }
    375393
    376394    /* Disconnect the client */
     
    475493int32_t crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer)
    476494{
    477     CRClient *pClient;
     495    CRClient *pClient=NULL;
    478496    int32_t i;
    479497
     
    485503            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
    486504        {
     505            pClient = cr_server.clients[i];
    487506            break;
    488507        }
    489508    }
    490     pClient = cr_server.clients[i];
    491     CRASSERT(pClient);
     509    if (!pClient) return VERR_INVALID_PARAMETER;   
    492510
    493511    if (!pClient->conn->vMajor) return VERR_NOT_SUPPORTED;
     
    519537int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor)
    520538{
    521     CRClient *pClient;
     539    CRClient *pClient=NULL;
    522540    int32_t i;
    523541
     
    527545            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
    528546        {
     547            pClient = cr_server.clients[i];
    529548            break;
    530549        }
    531550    }
    532     pClient = cr_server.clients[i];
    533     CRASSERT(pClient);
     551    if (!pClient) return VERR_INVALID_PARAMETER;
    534552
    535553    pClient->conn->vMajor = vMajor;
     
    542560    }
    543561    else return VINF_SUCCESS;
     562}
     563
     564int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid)
     565{
     566    CRClient *pClient=NULL;
     567    int32_t i;
     568
     569    for (i = 0; i < cr_server.numClients; i++)
     570    {
     571        if (cr_server.clients[i] && cr_server.clients[i]->conn
     572            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
     573        {
     574            pClient = cr_server.clients[i];
     575            break;
     576        }
     577    }
     578    if (!pClient) return VERR_INVALID_PARAMETER;
     579
     580    pClient->pid = pid;
     581
     582    return VINF_SUCCESS;
    544583}
    545584
     
    722761    /* Save cr_server.muralTable
    723762     * @todo we don't need it all, just geometry info actually
    724      * @todo store visible regions as well
    725763     */
    726764    ui32 = crHashtableNumElements(cr_server.muralTable);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c

    r32924 r33988  
    109109}
    110110
    111 
     111static void crServerCleanupClient(CRClient *client)
     112{
     113    int32_t pos;
     114    CRClient *oldclient = cr_server.curClient;
     115
     116    cr_server.curClient = client;
     117
     118    /* Destroy any windows created by the client */
     119    for (pos = 0; pos<CR_MAX_WINDOWS && client->windowList[pos]; pos++)
     120    {
     121        cr_server.dispatch.WindowDestroy(client->windowList[pos]);
     122    }
     123
     124    /* Check if we have context(s) made by this client left, could happen if client side code is lazy */
     125    for (pos = 0; pos<CR_MAX_CONTEXTS && client->contextList[pos]; pos++)
     126    {
     127        cr_server.dispatch.DestroyContext(client->contextList[pos]);
     128    }
     129
     130    cr_server.curClient = oldclient;
     131}
     132
     133static void crServerCleanupByPID(uint64_t pid)
     134{
     135    CRClientNode *pNode=cr_server.pCleanupClient, *pNext;
     136
     137    while (pNode)
     138    {
     139        if (pNode->pClient->pid==pid)
     140        {
     141            crServerCleanupClient(pNode->pClient);
     142            crFree(pNode->pClient);
     143            if (pNode->prev)
     144            {
     145                pNode->prev->next=pNode->next;
     146            }
     147            else
     148            {
     149                cr_server.pCleanupClient=pNode->next;
     150            }
     151            if (pNode->next)
     152            {
     153                pNode->next->prev = pNode->prev;
     154            }
     155
     156            pNext=pNode->next;
     157            crFree(pNode);
     158            pNode=pNext;
     159        }
     160        else
     161        {
     162            pNode=pNode->next;
     163        }
     164    }
     165}
    112166
    113167void
     
    115169{
    116170    int i, j;
    117     int32_t pos;
    118     CRClient *oldclient = cr_server.curClient;
     171    int cleanup=1;
    119172
    120173    crDebug("Deleting client %p (%d msgs left)", client, crNetNumMessages(client->conn));
     
    143196    }
    144197
    145     cr_server.curClient = client;
    146 
    147     /* Destroy any windows created by the client */
    148     for (pos = 0; pos<CR_MAX_WINDOWS && client->windowList[pos]; pos++)
    149     {
    150         cr_server.dispatch.WindowDestroy(client->windowList[pos]);
    151     }
    152 
    153     /* Check if we have context(s) made by this client left, could happen if client side code is lazy */
    154     for (pos = 0; pos<CR_MAX_CONTEXTS && client->contextList[pos]; pos++)
    155     {
    156         cr_server.dispatch.DestroyContext(client->contextList[pos]);
    157     }
    158 
    159     cr_server.curClient = oldclient;
     198    /* check if there're any other guest threads in same process */
     199    for (i=0; i < cr_server.numClients; i++)
     200    {
     201        if (cr_server.clients[i]->pid==client->pid)
     202        {
     203            cleanup=0;
     204            break;
     205        }
     206    }
     207
     208    if (cleanup)
     209    {
     210        crServerCleanupClient(client);
     211    }
    160212
    161213    /* remove from the run queue */
     
    195247
    196248    crNetFreeConnection(client->conn);
    197 
    198     crFree(client);
    199 }
    200 
     249    client->conn = NULL;
     250
     251    if (cleanup)
     252    {
     253        crServerCleanupByPID(client->pid);
     254        crFree(client);
     255    }
     256    else
     257    {
     258        CRClientNode *pNode = (CRClientNode *)crAlloc(sizeof(CRClientNode));
     259        if (!pNode)
     260        {
     261            crWarning("Not enough memory, forcing client cleanup");
     262            crServerCleanupClient(client);
     263            crServerCleanupByPID(client->pid);
     264            crFree(client);
     265            return;
     266        }
     267        pNode->pClient = client;
     268        pNode->prev = NULL;
     269        pNode->next = cr_server.pCleanupClient;
     270        cr_server.pCleanupClient = pNode;
     271    }
     272}
    201273
    202274/**
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r30011 r33988  
    117117}
    118118
     119static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
     120{
     121    int pos;
     122
     123    for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
     124    {
     125        if (pClient->windowList[pos] == window)
     126        {
     127            pClient->windowList[pos] = 0;
     128            return true;
     129        }
     130    }
     131
     132    return false;
     133}
     134
    119135void SERVER_DISPATCH_APIENTRY
    120136crServerDispatchWindowDestroy( GLint window )
     
    122138    CRMuralInfo *mural;
    123139    int32_t client;
    124     int pos;
     140    CRClientNode *pNode;
     141    int found=false;
    125142
    126143    mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
     
    148165        }
    149166
    150         for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
    151             if (cr_server.curClient->windowList[pos] == window)
    152             {
    153                 cr_server.curClient->windowList[pos] = 0;
    154                 break;
    155             }
     167        found = crServerRemoveClientWindow(cr_server.curClient, window);
    156168
    157169        /*Same as with contexts, some apps destroy it not in a thread where it was created*/
    158         if (CR_MAX_WINDOWS==pos)
     170        if (!found)
    159171        {
    160172            for (client=0; client<cr_server.numClients; ++client)
     
    163175                    continue;
    164176
    165                 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
    166                     if (cr_server.clients[client]->windowList[pos] == window)
    167                     {
    168                         cr_server.clients[client]->windowList[pos] = 0;
    169                         break;
    170                     }
    171 
    172                 if (pos<CR_MAX_WINDOWS)
    173                 {
    174                     if (cr_server.clients[client]->currentMural == mural)
    175                     {
    176                         cr_server.clients[client]->currentMural = NULL;
    177                         cr_server.clients[client]->currentWindow = -1;
    178                     }
    179                     break;
    180                 }
    181             }
    182         }
    183 
    184         CRASSERT(pos<CR_MAX_WINDOWS);
     177                found = crServerRemoveClientWindow(cr_server.clients[client], window);
     178
     179                if (found) break;
     180            }
     181        }
     182
     183        if (!found)
     184        {
     185            pNode=cr_server.pCleanupClient;
     186
     187            while (pNode && !found)
     188            {
     189                found = crServerRemoveClientWindow(pNode->pClient, window);
     190                pNode = pNode->next;
     191            }
     192        }
     193
     194        CRASSERT(found);
    185195    }
    186196
     
    195205    }
    196206
     207    pNode=cr_server.pCleanupClient;
     208    while (pNode)
     209    {
     210        if (pNode->pClient->currentMural == mural)
     211        {
     212            pNode->pClient->currentMural = NULL;
     213            pNode->pClient->currentWindow = -1;
     214        }
     215        pNode = pNode->next;
     216    }
     217
    197218    crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
    198219
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette