VirtualBox

Changeset 29040 in vbox


Ignore:
Timestamp:
May 4, 2010 8:09:03 PM (15 years ago)
Author:
vboxsync
Message:

VBoxService/PropCache: Finished some todos, IPRT: Added VINF_NO_CHANGE.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r28800 r29040  
    503503/** Retry the operation. */
    504504#define VINF_TRY_AGAIN                      52
     505/** No change done. */
     506#define VINF_NO_CHANGE                      53
    505507/** Generic parse error. */
    506508#define VERR_PARSE_ERROR                    (-53)
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r29026 r29040  
    2626
    2727#include <iprt/list.h>
    28 #include <iprt/semaphore.h>
     28#include <iprt/critsect.h>
    2929
    3030/**
     
    139139    uint32_t    cbOffset;
    140140    uint32_t    cbRead;
    141     RTSEMMUTEX  mtx;
     141    RTCRITSECT  CritSect;
    142142} VBOXSERVICECTRLEXECPIPEBUF;
    143143/** Pointer to thread data. */
     
    169169
    170170/* Structure for holding thread relevant data. */
    171 typedef struct
     171typedef struct VBOXSERVICECTRLTHREAD
    172172{
    173173    /** Node. */
     
    224224    /** The client ID for HGCM communication. */
    225225    uint32_t    uClientID;
    226     /** List of VBOXSERVICEVEPROPCACHEENTRY nodes.
    227      * @todo r=bird: Node -> ListSomething, please.  "Node" is very nondescript and
    228      *       makes the list-head vs. list-node confusion greater. */
    229     RTLISTNODE  Node;
    230     /** @todo Use a RTCRITSECT. RTSEMMUTEXes are deprecated in ring-3. */
    231     RTSEMMUTEX  Mutex;
     226    /** List of VBOXSERVICEVEPROPCACHEENTRY nodes. */
     227    RTLISTNODE  ListEntries;
     228    /** Critical section for thread-safe use. */
     229    RTCRITSECT  CritSect;
    232230} VBOXSERVICEVEPROPCACHE;
    233231/** Pointer to a guest property cache. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp

    r29026 r29040  
    3131
    3232
    33 /**
    34  * Initializes the property cache.
    35  *
    36  * @returns IPRT status code.
    37  * @param   pCache          Pointer to the cache.
    38  * @param   uClientId       The HGCM handle of to the guest property service.
    39  */
    40 int VBoxServicePropCacheInit(PVBOXSERVICEVEPROPCACHE pCache, uint32_t uClientId)
    41 {
    42     AssertPtr(pCache);
    43     /** @todo Prevent init the cache twice!
    44      *  r=bird: Use a magic, or/and abstract the whole cache by rename this function
    45      *  VBoxServicePropCacheCreate(). */
    46     RTListInit(&pCache->Node);
    47     pCache->uClientID = uClientId;
    48     return RTSemMutexCreate(&pCache->Mutex);
    49 }
    50 
    51 
    52 /** @todo Docs
    53  * @todo this looks internal to me, nobody should need to access the
    54  *       structures directly here. */
    55 PVBOXSERVICEVEPROPCACHEENTRY VBoxServicePropCacheFind(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t uFlags)
     33/** Internal functions, not for public use. */
     34PVBOXSERVICEVEPROPCACHEENTRY vboxServicePropCacheFindInternal(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t uFlags);
     35PVBOXSERVICEVEPROPCACHEENTRY vboxServicePropCacheInsertEntryInternal(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName);
     36
     37
     38/** @todo Docs */
     39PVBOXSERVICEVEPROPCACHEENTRY vboxServicePropCacheFindInternal(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t uFlags)
    5640{
    5741    AssertPtr(pCache);
     
    6347     *        moment. */
    6448    PVBOXSERVICEVEPROPCACHEENTRY pNodeIt, pNode = NULL;
    65     if (RT_SUCCESS(RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT)))
    66     {
    67         RTListForEach(&pCache->Node, pNodeIt, VBOXSERVICEVEPROPCACHEENTRY, Node)
     49    if (RT_SUCCESS(RTCritSectEnter(&pCache->CritSect)))
     50    {
     51        RTListForEach(&pCache->ListEntries, pNodeIt, VBOXSERVICEVEPROPCACHEENTRY, Node)
    6852        {
    6953            if (strcmp(pNodeIt->pszName, pszName) == 0)
     
    7357            }
    7458        }
    75         RTSemMutexRelease(pCache->Mutex);
     59        RTCritSectLeave(&pCache->CritSect);
    7660    }
    7761    return pNode;
     62}
     63
     64
     65/** @todo Docs */
     66PVBOXSERVICEVEPROPCACHEENTRY vboxServicePropCacheInsertEntryInternal(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName)
     67{
     68    AssertPtr(pszName);
     69    PVBOXSERVICEVEPROPCACHEENTRY pNode = (PVBOXSERVICEVEPROPCACHEENTRY)RTMemAlloc(sizeof(VBOXSERVICEVEPROPCACHEENTRY));
     70    if (pNode)
     71    {
     72        pNode->pszName = RTStrDup(pszName);
     73        pNode->pszValue = NULL;
     74        pNode->fFlags = 0;
     75        pNode->pszValueReset = NULL;
     76
     77        int rc = RTCritSectEnter(&pCache->CritSect);
     78        if (RT_SUCCESS(rc))
     79        {
     80            /*rc =*/ RTListAppend(&pCache->ListEntries, &pNode->Node);
     81            rc = RTCritSectLeave(&pCache->CritSect);
     82        }
     83    }
     84    return pNode;
     85}
     86
     87
     88/**
     89 * Creates a property cache.
     90 *
     91 * @returns IPRT status code.
     92 * @param   pCache          Pointer to the cache.
     93 * @param   uClientId       The HGCM handle of to the guest property service.
     94 */
     95int VBoxServicePropCacheCreate(PVBOXSERVICEVEPROPCACHE pCache, uint32_t uClientId)
     96{
     97    AssertPtr(pCache);
     98    /** @todo Prevent init the cache twice!
     99     *  r=bird: Use a magic. */
     100    RTListInit(&pCache->ListEntries);
     101    pCache->uClientID = uClientId;
     102    return RTCritSectInit(&pCache->CritSect);
    78103}
    79104
     
    85110    AssertPtr(pCache);
    86111    AssertPtr(pszName);
    87     PVBOXSERVICEVEPROPCACHEENTRY pNode = VBoxServicePropCacheFind(pCache, pszName, 0);
     112    PVBOXSERVICEVEPROPCACHEENTRY pNode = vboxServicePropCacheFindInternal(pCache, pszName, 0);
     113    if (pNode == NULL)
     114        pNode = vboxServicePropCacheInsertEntryInternal(pCache, pszName);
     115
    88116    int rc;
    89117    if (pNode != NULL)
    90118    {
    91         rc = RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT);
     119        rc = RTCritSectEnter(&pCache->CritSect);
    92120        if (RT_SUCCESS(rc))
    93121        {
     
    95123            if (pszValueReset)
    96124            {
    97                 if (pszValueReset)
     125                if (pNode->pszValueReset)
    98126                    RTStrFree(pNode->pszValueReset);
    99127                pNode->pszValueReset = RTStrDup(pszValueReset);
    100128            }
    101             rc = RTSemMutexRelease(pCache->Mutex);
     129            rc = RTCritSectLeave(&pCache->CritSect);
    102130        }
    103131    }
    104132    else
    105         rc = VERR_NOT_FOUND;
     133        rc = VERR_NO_MEMORY;
    106134    return rc;
    107135}
     
    169197    }
    170198
    171     PVBOXSERVICEVEPROPCACHEENTRY pNode = VBoxServicePropCacheFind(pCache, pszName, 0);
     199    PVBOXSERVICEVEPROPCACHEENTRY pNode = vboxServicePropCacheFindInternal(pCache, pszName, 0);
    172200
    173201    /* Lock the cache. */
    174     int rc = RTSemMutexRequest(pCache->Mutex, RT_INDEFINITE_WAIT);
     202    int rc = RTCritSectEnter(&pCache->CritSect);
    175203    if (RT_SUCCESS(rc))
    176204    {
    177 
    178205        if (pNode == NULL)
    179         {
    180             pNode = (PVBOXSERVICEVEPROPCACHEENTRY)RTMemAlloc(sizeof(VBOXSERVICEVEPROPCACHEENTRY));
    181             if (RT_UNLIKELY(!pNode))
    182             {
    183                 RTSemMutexRelease(pCache->Mutex);
    184                 return VERR_NO_MEMORY;
    185             }
    186 
    187             pNode->pszName = RTStrDup(pszName);
    188             pNode->pszValue = NULL;
    189             pNode->fFlags = 0;
    190             pNode->pszValueReset = NULL;
    191 
    192             /*rc =*/ RTListAppend(&pCache->Node, &pNode->Node);
    193         }
     206            pNode = vboxServicePropCacheInsertEntryInternal(pCache, pszName);
    194207
    195208        AssertPtr(pNode);
     
    215228            }
    216229            else
    217                 /** @todo r=bird: Add a VINF_NO_CHANGE status code to iprt/err.h and use it. */
    218                 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */
     230                rc = VINF_NO_CHANGE; /* No update needed. */
    219231        }
    220232        else
     
    229241            }
    230242            else
    231                 /** @todo r=bird: Use VINF_NO_CHANGE. */
    232                 rc = VINF_ALREADY_INITIALIZED; /* No update needed. */
     243                rc = VINF_NO_CHANGE; /* No update needed. */
    233244        }
    234245
     
    244255
    245256        /* Release cache. */
    246         int rc2 = RTSemMutexRelease(pCache->Mutex);
     257        int rc2 = RTCritSectLeave(&pCache->CritSect);
    247258        if (RT_SUCCESS(rc))
    248259            rc2 = rc;
     
    265276    AssertPtr(pCache);
    266277    Assert(pCache->uClientID);
    267     PVBOXSERVICEVEPROPCACHEENTRY pNode;
    268     RTListForEach(&pCache->Node, pNode, VBOXSERVICEVEPROPCACHEENTRY, Node)
    269     {
    270         if ((pNode->fFlags & VBOXSERVICEPROPCACHEFLAG_TEMPORARY) == 0)
    271             VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, pNode->pszValueReset);
    272 
    273         AssertPtr(pNode->pszName);
    274         RTStrFree(pNode->pszName);
    275         RTStrFree(pNode->pszValue);
    276         RTStrFree(pNode->pszValueReset);
    277         pNode->fFlags = 0;
    278     }
    279 
    280     pNode = RTListNodeGetFirst(&pCache->Node, VBOXSERVICEVEPROPCACHEENTRY, Node);
    281     while (pNode)
    282     {
    283         PVBOXSERVICEVEPROPCACHEENTRY pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICEVEPROPCACHEENTRY, Node);
    284         RTListNodeRemove(&pNode->Node);
    285         /** @todo r=bird: hrm. missing RTMemFree(pNode)? Why don't you just combine the
    286          *        two loops? */
    287 
    288         if (pNext && RTListNodeIsLast(&pCache->Node, &pNext->Node))
    289             break;
    290         pNode = pNext;
    291     }
    292 
    293     /* Destroy mutex. */
    294     RTSemMutexDestroy(pCache->Mutex);
    295 }
    296 
     278
     279    /* Lock the cache. */
     280    int rc = RTCritSectEnter(&pCache->CritSect);
     281    if (RT_SUCCESS(rc))
     282    {
     283        PVBOXSERVICEVEPROPCACHEENTRY pNode = RTListNodeGetFirst(&pCache->ListEntries, VBOXSERVICEVEPROPCACHEENTRY, Node);
     284        while (pNode)
     285        {
     286            if ((pNode->fFlags & VBOXSERVICEPROPCACHEFLAG_TEMPORARY) == 0)
     287                VBoxServiceWritePropF(pCache->uClientID, pNode->pszName, pNode->pszValueReset);
     288   
     289            AssertPtr(pNode->pszName);
     290            RTStrFree(pNode->pszName);
     291            RTStrFree(pNode->pszValue);
     292            RTStrFree(pNode->pszValueReset);
     293            pNode->fFlags = 0;
     294   
     295            PVBOXSERVICEVEPROPCACHEENTRY pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICEVEPROPCACHEENTRY, Node);
     296            RTListNodeRemove(&pNode->Node);
     297            RTMemFree(pNode);
     298   
     299            if (pNext && RTListNodeIsLast(&pCache->ListEntries, &pNext->Node))
     300                break;
     301            pNode = pNext;
     302        }
     303        RTCritSectLeave(&pCache->CritSect);
     304    }
     305
     306    /* Destroy critical section. */
     307    RTCritSectDelete(&pCache->CritSect);
     308}
     309
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.h

    r29026 r29040  
    2626#define VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE      RT_BIT(2)
    2727
    28 int VBoxServicePropCacheInit(PVBOXSERVICEVEPROPCACHE pCache, uint32_t uClientId);
    29 PVBOXSERVICEVEPROPCACHEENTRY VBoxServicePropCacheFind(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t uFlags);
     28int VBoxServicePropCacheCreate(PVBOXSERVICEVEPROPCACHE pCache, uint32_t uClientId);
    3029int VBoxServicePropCacheUpdateEntry(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t fFlags, const char *pszValueReset);
    3130int VBoxServicePropCacheUpdate(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, const char *pszValueFormat, ...);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp

    r29026 r29040  
    129129    if (RT_SUCCESS(rc))
    130130    {
    131         VBoxServicePropCacheInit(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
     131        VBoxServicePropCacheCreate(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
    132132
    133133        /** @todo r=bird: Setting Net/Count to 0 here is wrong and will confuse users.
     
    139139
    140140        /*
    141          * Set flags and reset values for some guest proerties that need to have that.
    142          * Passing NULL as an actual value does not write the properties yet.
     141         * Initialize some guest properties to have flags and reset values.
    143142         */
    144         VBoxServicePropCacheUpdateEx(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
    145                                      VBOXSERVICEPROPCACHEFLAG_TEMPORARY, NULL /* Delete on exit */, NULL);
    146         VBoxServicePropCacheUpdateEx(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
    147                                      VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "0", NULL);
    148         VBoxServicePropCacheUpdateEx(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
    149                                      VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "true", NULL);
    150         /*
    151          * This property is a beacon which is _always_ written, even if the network configuration
    152          * does not change. If this property is missing, the host assumes that all other GuestInfo
    153          * properties are no longer valid.
    154          */
    155         VBoxServicePropCacheUpdateEx(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
    156                                      VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, "0", NULL);
     143        VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
     144                                        VBOXSERVICEPROPCACHEFLAG_TEMPORARY, NULL /* Delete on exit */);
     145        VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
     146                                        VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "0");
     147        VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
     148                                        VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "true");
     149        VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
     150                                        VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
    157151    }
    158152    return rc;
     
    412406        int iCurIface = 0;
    413407
    414         /** @todo r=bird: As mentioned in the defect, this must be written after ALL
    415          *        the other values since it indicates that they are up-to-date by its
    416          *        timestamp. */
    417         VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
    418                                    cInterfaces > 1 ? cInterfaces-1 : 0);
    419 
    420408        /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
    421409        for (int i = 0; i < cInterfaces; ++i)
     
    485473            close(sd);
    486474#endif
     475
     476        /*
     477         * This property is a beacon which is _always_ written, even if the network configuration
     478         * does not change. If this property is missing, the host assumes that all other GuestInfo
     479         * properties are no longer valid.
     480         *
     481         * cInterfaces also counts in local loopback, but we don't want to report that.
     482         */
     483        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
     484                                   cInterfaces > 1 ? cInterfaces-1 : 0);
     485
    487486        /** @todo r=bird: if cInterfaces decreased compared to the previous run, zap
    488487         *        the stale data. */
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