VirtualBox

Changeset 33988 in vbox


Ignore:
Timestamp:
Nov 11, 2010 1:03:17 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67651
Message:

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

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h

    r33146 r33988  
    4848#define SHCRGL_GUEST_FN_SET_VERSION (6)
    4949#define SHCRGL_GUEST_FN_INJECT      (9)
     50#define SHCRGL_GUEST_FN_SET_PID     (12)
    5051
    5152/* Parameters count */
     
    5960#define SHCRGL_CPARMS_SCREEN_CHANGED (1)
    6061#define SHCRGL_CPARMS_INJECT (2)
     62#define SHCRGL_CPARMS_SET_PID (1)
    6163
    6264#ifdef VBOX_WITH_CRHGSMI
     
    140142    uint32_t iBuffer;
    141143} CRVBOXHGSMIINJECT;
     144
     145/** GUEST_FN_SET_PID Parameters structure. */
     146typedef struct
     147{
     148    CRVBOXHGSMIHDR hdr;
     149
     150    /** 64bit, in
     151     *  PID
     152     */
     153    uint64_t   u64PID;
     154} CRVBOXHGSMISETPID;
     155
    142156#pragma pack()
    143157#endif
     
    228242} CRVBOXHGCMINJECT;
    229243
     244/** GUEST_FN_SET_PID Parameters structure. */
     245typedef struct
     246{
     247    VBoxGuestHGCMCallInfo   hdr;
     248
     249    /** 64bit, in
     250     *  PID
     251     */
     252    HGCMFunctionParameter   u64PID;
     253} CRVBOXHGCMSETPID;
     254
    230255#endif
  • trunk/src/VBox/Additions/common/crOpenGL/load.c

    r33540 r33988  
    11821182    }
    11831183
     1184#if 0
    11841185    case DLL_THREAD_ATTACH:
     1186    {
     1187        if (stub_initialized)
     1188        {
     1189            CRASSERT(stub.spu);
     1190            stub.spu->dispatch_table.VBoxPackAttachThread();
     1191        }
    11851192        break;
     1193    }
    11861194
    11871195    case DLL_THREAD_DETACH:
     1196    {
     1197        if (stub_initialized)
     1198        {
     1199            CRASSERT(stub.spu);
     1200            stub.spu->dispatch_table.VBoxPackDetachThread();
     1201        }
    11881202        break;
     1203    }
     1204#endif
    11891205
    11901206    default:
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu.h

    r30440 r33988  
    3636    int writeback;
    3737    GLboolean bInjectThread;
     38    GLboolean inUse;
    3839};
    3940
     
    6061    int buffer_size;
    6162
    62     int numThreads;
     63    int numThreads; /*number of used threads in the next array, doesn't need to be cont*/
    6364    ThreadInfo thread[MAX_THREADS];
     65    int idxThreadInUse; /*index of any used thread*/
    6466
    6567    int numContexts;
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c

    r30440 r33988  
    2323ThreadInfo *packspuNewThread( unsigned long id )
    2424{
    25     ThreadInfo *thread;
     25    ThreadInfo *thread=NULL;
     26    int i;
    2627
    2728#ifdef CHROMIUM_THREADSAFE
     
    3233
    3334    CRASSERT(pack_spu.numThreads < MAX_THREADS);
    34     thread = &(pack_spu.thread[pack_spu.numThreads]);
    35 
     35    for (i=0; i<MAX_THREADS; ++i)
     36    {
     37        if (!pack_spu.thread[i].inUse)
     38        {
     39            thread = &pack_spu.thread[i];
     40            break;
     41        }
     42    }
     43    CRASSERT(thread);
     44
     45    thread->inUse = GL_TRUE;
    3646    thread->id = id;
    3747    thread->currentContext = NULL;
     
    5060    else {
    5161        /* a new pthread */
    52         crNetNewClient(pack_spu.thread[0].netServer.conn, &(thread->netServer));
     62        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
    5363        CRASSERT(thread->netServer.conn);
    5464    }
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py

    r27889 r33988  
    6565        if (func_name in easy_swaps.keys() and easy_swaps[func_name] != '0') or func_name in simple_funcs or func_name in hard_funcs.keys():
    6666            print '\tunsigned int i;'
    67         print '\tif (!(pack_spu.thread[0].netServer.conn->actual_network))'
     67        print '\tif (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))'
    6868        print '\t{'
    6969        print '\t\tcrError( "packspu_%s doesn\'t work when there\'s no actual network involved!\\nTry using the simplequery SPU in your chain!" );' % func_name
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c

    r28800 r33988  
    2929    int writeback = 1;
    3030    GLuint return_val = (GLuint) 0;
    31     if (!(pack_spu.thread[0].netServer.conn->actual_network))
     31    if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
    3232    {
    3333        crError("packspu_CreateProgram doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
     
    5959    int writeback = 1;
    6060    GLint return_val = (GLint) 0;
    61     if (!(pack_spu.thread[0].netServer.conn->actual_network))
     61    if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
    6262    {
    6363        crError("packspu_GetUniformLocation doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c

    r33475 r33988  
    3939    (void) self;
    4040
    41 #ifdef CHROMIUM_THREADSAFE
     41#if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS)
    4242    crInitMutex(&_PackMutex);
    4343#endif
     
    5454    }
    5555    CRASSERT( thread == &(pack_spu.thread[0]) );
     56    pack_spu.idxThreadInUse = 0;
    5657
    5758    packspuCreateFunctions();
     
    7475    crLockMutex(&_PackMutex);
    7576#endif
    76     for (i=0; i<pack_spu.numThreads; ++i)
     77    for (i=0; i<MAX_THREADS; ++i)
    7778    {
    78         if (pack_spu.thread[i].packer)
     79        if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer)
    7980        {
    8081            crPackDeleteContext(pack_spu.thread[i].packer);
     
    8788#ifdef CHROMIUM_THREADSAFE
    8889    crUnlockMutex(&_PackMutex);
     90# ifndef WINDOWS
    8991    crFreeMutex(&_PackMutex);
     92# endif
    9093#endif
    9194    return 1;
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c

    r30486 r33988  
    88#include "packspu.h"
    99#include "packspu_proto.h"
     10#include "cr_mem.h"
    1011
    1112void PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
     
    7576{
    7677    GET_THREAD(thread);
    77     GLint writeback = pack_spu.thread[0].netServer.conn->actual_network;
     78    GLint writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
    7879
    7980    if (pack_spu.swap)
     
    125126        crLockMutex(&_PackMutex);
    126127        /*Make sure we process commands in order they should appear, so flush thread being injected first*/
    127         for (i=0; i<pack_spu.numThreads; ++i)
    128         {
    129             if ((thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
     128        for (i=0; i<MAX_THREADS; ++i)
     129        {
     130            if (pack_spu.thread[i].inUse
     131                && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
    130132                && (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
    131133                && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
     
    135137            }
    136138        }
     139        if (i>=MAX_THREADS)
     140        {
     141            crWarning("packspu: inject for invalid client id");
     142        }
    137143        crUnlockMutex(&_PackMutex);
    138144
     
    145151    GET_THREAD(thread);
    146152    static int num_calls = 0;
    147     int writeback = pack_spu.thread[0].netServer.conn->actual_network;
     153    int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
    148154    GLint return_val = (GLint) 0;
    149155
     
    192198    GLsizei i;
    193199
    194     if (!(pack_spu.thread[0].netServer.conn->actual_network))
     200    if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
    195201    {
    196202        crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
     
    233239    GLsizei i;
    234240
    235     if (!(pack_spu.thread[0].netServer.conn->actual_network))
     241    if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
    236242    {
    237243        crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
     
    364370    crLockMutex(&_PackMutex);
    365371    {
     372        int i;
    366373        GET_THREAD(thread);
    367374        CRASSERT(!thread);
    368375        CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS));
    369376
    370         thread = &(pack_spu.thread[pack_spu.numThreads]);
     377        for (i=0; i<MAX_THREADS; ++i)
     378        {
     379            if (!pack_spu.thread[i].inUse)
     380            {
     381                thread = &pack_spu.thread[i];
     382                break;
     383            }
     384        }
     385        CRASSERT(thread);
     386
     387        thread->inUse = GL_TRUE;
    371388        thread->id = crThreadID();
    372389        thread->currentContext = NULL;
     
    376393        thread->netServer.buffer_size = 64 * 1024;
    377394
    378         crNetNewClient(pack_spu.thread[0].netServer.conn, &(thread->netServer));
     395        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
    379396        CRASSERT(thread->netServer.conn);
    380397
     
    424441    crUnlockMutex(&_PackMutex);
    425442}
     443
     444void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
     445{
     446#if 0
     447    int i;
     448    GET_THREAD(thread);
     449
     450    for (i=0; i<MAX_THREADS; ++i)
     451    {
     452        if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
     453        {
     454            crError("2nd attach to same thread");
     455        }
     456    }
     457#endif
     458
     459    crSetTSD(&_PackTSD, NULL);
     460}
     461
     462void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
     463{
     464    int i;
     465    GET_THREAD(thread);
     466
     467    if (thread)
     468    {
     469        crLockMutex(&_PackMutex);
     470
     471        for (i=0; i<MAX_THREADS; ++i)
     472        {
     473            if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
     474                && thread->id==crThreadID() && thread->netServer.conn)
     475            {
     476                CRASSERT(pack_spu.numThreads>0);
     477
     478                packspuFlush((void *) thread);
     479
     480                if (pack_spu.thread[i].packer)
     481                {
     482                    CR_LOCK_PACKER_CONTEXT(thread->packer);
     483                    crPackSetContext(NULL);
     484                    CR_UNLOCK_PACKER_CONTEXT(thread->packer);
     485                    crPackDeleteContext(pack_spu.thread[i].packer);
     486                }
     487                crNetFreeConnection(pack_spu.thread[i].netServer.conn);
     488
     489                pack_spu.numThreads--;
     490                /*note can't shift the array here, because other threads have TLS references to array elements*/
     491                crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
     492
     493                crSetTSD(&_PackTSD, NULL);
     494
     495                if (i==pack_spu.idxThreadInUse)
     496                {
     497                    for (i=0; i<MAX_THREADS; ++i)
     498                    {
     499                        if (pack_spu.thread[i].inUse)
     500                        {
     501                            pack_spu.idxThreadInUse=i;
     502                            break;
     503                        }
     504                    }
     505                }
     506
     507                break;
     508            }
     509        }
     510
     511        crUnlockMutex(&_PackMutex);
     512    }
     513}
     514
     515#ifdef WINDOWS
     516#define WIN32_LEAN_AND_MEAN
     517#include <windows.h>
     518BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
     519{
     520    (void) lpvReserved;
     521
     522    switch (fdwReason)
     523    {
     524        case DLL_PROCESS_ATTACH:
     525        {
     526            crInitMutex(&_PackMutex);
     527            break;
     528        }
     529
     530        case DLL_PROCESS_DETACH:
     531        {
     532            crFreeMutex(&_PackMutex);
     533            break;
     534        }
     535
     536        case DLL_THREAD_ATTACH:
     537        {
     538            packspu_VBoxPackAttachThread();
     539            break;
     540        }
     541
     542        case DLL_THREAD_DETACH:
     543        {
     544            packspu_VBoxPackDetachThread();
     545            break;
     546        }
     547
     548        default:
     549            break;
     550    }
     551
     552    return TRUE;
     553}
     554#endif
     555
    426556#else  /*ifdef CHROMIUM_THREADSAFE*/
    427557void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
     
    438568    (void) id;
    439569}
     570
     571void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
     572{
     573}
     574
     575void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
     576{
     577}
    440578#endif /*CHROMIUM_THREADSAFE*/
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_special

    r30440 r33988  
    105105VBoxPackGetInjectID
    106106VBoxPackSetInjectID
     107VBoxPackAttachThread
     108VBoxPackDetachThread
  • trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt

    r33540 r33988  
    85168516chromium    nopack
    85178517
     8518name        VBoxPackAttachThread
     8519return      void
     8520category    VBox
     8521chromium    nopack
     8522
     8523name        VBoxPackDetachThread
     8524return      void
     8525category    VBox
     8526chromium    nopack
     8527
    85188528# OpenGL 1.5
    85198529
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r33750 r33988  
    2626#endif
    2727
    28 #define SHCROGL_SSM_VERSION 21
     28#define SHCROGL_SSM_VERSION 22
    2929
    3030#define CR_MAX_WINDOWS 100
     
    7878    CRConnection *conn;       /**< network connection from the client */
    7979    int number;        /**< a unique number for each client */
     80    uint64_t pid;      /*guest pid*/
    8081    GLint currentContextNumber;
    8182    CRContext *currentCtx;
     
    8990} CRClient;
    9091
     92typedef struct _crclientnode {
     93    CRClient *pClient;
     94    struct _crclientnode *prev, *next;
     95} CRClientNode;
     96
    9197typedef struct CRPoly_t {
    9298    int npoints;
     
    127133    CRClient *clients[CR_MAX_CLIENTS];  /**< array [numClients] */
    128134    CRClient *curClient;
     135    CRClientNode *pCleanupClient;  /*list of clients with pending clean up*/
    129136    CRCurrentStatePointers current;
    130137
     
    238245extern DECLEXPORT(int32_t) crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer);
    239246extern DECLEXPORT(int32_t) crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor);
     247extern DECLEXPORT(int32_t) crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid);
    240248
    241249extern DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM);
  • trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c

    r33929 r33988  
    3535#include "cr_threads.h"
    3636#include "net_internals.h"
     37#include "cr_process.h"
    3738
    3839#include <iprt/thread.h>
     
    12501251}
    12511252
     1253static int crVBoxHGCMSetPID(CRConnection *conn, CRpid pid)
     1254{
     1255    CRVBOXHGCMSETPID parms;
     1256    int rc;
     1257
     1258    parms.hdr.result      = VERR_WRONG_ORDER;
     1259    parms.hdr.u32ClientID = conn->u32ClientID;
     1260    parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_PID;
     1261    parms.hdr.cParms      = SHCRGL_CPARMS_SET_PID;
     1262
     1263    parms.u64PID.type     = VMMDevHGCMParmType_64bit;
     1264    parms.u64PID.u.value64 = (uintptr_t) pid;
     1265
     1266    rc = crVBoxHGCMCall(&parms, sizeof(parms));
     1267
     1268    if (RT_FAILURE(rc) || RT_FAILURE(parms.hdr.result))
     1269    {
     1270        Assert(0);
     1271
     1272        crWarning("SHCRGL_GUEST_FN_SET_PID failed!");
     1273        return FALSE;
     1274    }
     1275
     1276    return TRUE;
     1277}
     1278
    12521279/**
    12531280 * The function that actually connects.  This should only be called by clients,
     
    13221349    if (ioctl(g_crvboxhgcm.iGuestDrv, VBOXGUEST_IOCTL_HGCM_CONNECT, &Hdr) >= 0)
    13231350#else
    1324     /*@todo it'd fail */
    13251351    if (ioctl(g_crvboxhgcm.iGuestDrv, VBOXGUEST_IOCTL_HGCM_CONNECT, &info, sizeof (info)) >= 0)
    13261352#endif
     
    13281354        if (info.result == VINF_SUCCESS)
    13291355        {
     1356            int rc;
    13301357            conn->u32ClientID = info.u32ClientID;
    13311358            crDebug("HGCM connect was successful: client id =0x%x\n", conn->u32ClientID);
    13321359
     1360            rc = crVBoxHGCMSetVersion(conn, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR);
     1361            if (!rc)
     1362            {
     1363                return rc;
     1364            }
     1365            rc = crVBoxHGCMSetPID(conn, crGetPID());
    13331366            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
    1334             return crVBoxHGCMSetVersion(conn, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR);
     1367            return rc;
    13351368        }
    13361369        else
  • trunk/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c

    r33595 r33988  
    3737#include "cr_threads.h"
    3838#include "net_internals.h"
     39#include "cr_process.h"
    3940
    4041#include <iprt/thread.h>
     
    11711172}
    11721173
     1174static int crVBoxHGSMISetPID(CRConnection *conn, CRpid pid)
     1175{
     1176    CRVBOXHGCMSETPID parms;
     1177    int rc;
     1178
     1179    parms.hdr.result      = VERR_WRONG_ORDER;
     1180    parms.hdr.u32ClientID = conn->u32ClientID;
     1181    parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_PID;
     1182    parms.hdr.cParms      = SHCRGL_CPARMS_SET_PID;
     1183
     1184    parms.u64PID.type     = VMMDevHGCMParmType_64bit;
     1185    parms.u64PID.u.value64 = (uintptr_t) pid;
     1186
     1187    rc = crVBoxHGCMCall(&parms, sizeof(parms));
     1188
     1189    if (RT_FAILURE(rc) || RT_FAILURE(parms.hdr.result))
     1190    {
     1191        Assert(0);
     1192
     1193        crWarning("SHCRGL_GUEST_FN_SET_PID failed!");
     1194        return FALSE;
     1195    }
     1196
     1197    return TRUE;
     1198}
     1199
    11731200/**
    11741201 * The function that actually connects.  This should only be called by clients,
     
    12421269    if (ioctl(g_crvboxhgsmi.iGuestDrv, VBOXGUEST_IOCTL_HGCM_CONNECT, &Hdr) >= 0)
    12431270#else
    1244     /*@todo it'd fail */
    12451271    if (ioctl(g_crvboxhgsmi.iGuestDrv, VBOXGUEST_IOCTL_HGCM_CONNECT, &info, sizeof (info)) >= 0)
    12461272#endif
     
    12531279
    12541280            rc = crVBoxHGSMISetVersion(conn, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR);
     1281            if (!rc)
     1282            {
     1283                return rc;
     1284            }
     1285            rc = crVBoxHGCMSetPID(conn, crGetPID());
    12551286            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
    12561287            return rc;
  • 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.

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