VirtualBox

Ignore:
Timestamp:
Apr 2, 2015 12:17:22 AM (10 years ago)
Author:
vboxsync
Message:

Main/HostDnsService: registry updates for multiple values are not
atomic, so wait a bit after registry notification to avoid racing and
reading partial update.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp

    r54662 r55085  
    3535{
    3636    HKEY hKeyTcpipParameters;
     37    bool fTimerArmed;
    3738
    3839#define DATA_SHUTDOWN_EVENT   0
    3940#define DATA_DNS_UPDATE_EVENT 1
    40 #define DATA_MAX_EVENT        2
     41#define DATA_TIMER            2
     42#define DATA_MAX_EVENT        3
    4143    HANDLE haDataEvent[DATA_MAX_EVENT];
    4244
     
    4446    {
    4547        hKeyTcpipParameters = NULL;
     48        fTimerArmed = false;
    4649
    4750        for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
     
    8184    for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
    8285    {
    83         data->haDataEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
    84         if (data->haDataEvent[i] == NULL)
     86        HANDLE h;
     87
     88        if (i ==  DATA_TIMER)
     89            h = CreateWaitableTimer(NULL, FALSE, NULL);
     90        else
     91            h = CreateEvent(NULL, TRUE, FALSE, NULL);
     92
     93        if (h == NULL)
    8594        {
    8695            LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError()));
    8796            return;
    8897        }
     98
     99        data->haDataEvent[i] = h;
    89100    }
    90101
     
    156167        if (dwReady == WAIT_OBJECT_0 + DATA_DNS_UPDATE_EVENT)
    157168        {
    158             updateInfo();
     169            /*
     170             * Registry updates for multiple values are not atomic, so
     171             * wait a bit to avoid racing and reading partial update.
     172             */
     173            if (!m->fTimerArmed)
     174            {
     175                LARGE_INTEGER delay; /* in 100ns units */
     176                delay.QuadPart = -2 * 1000 * 1000 * 10LL; /* relative: 2s */
     177
     178                BOOL ok = SetWaitableTimer(m->haDataEvent[DATA_TIMER], &delay,
     179                                           0, NULL, NULL, TRUE);
     180                if (ok)
     181                {
     182                    m->fTimerArmed = true;
     183                }
     184                else
     185                {
     186                    LogRel(("HostDnsServiceWin: failed to arm timer (error %d)\n", GetLastError()));
     187                    updateInfo();
     188                }
     189            }
    159190
    160191            ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
    161192            registerNotification(m->hKeyTcpipParameters,
    162193                                 m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
    163 
     194        }
     195        else if (dwReady == WAIT_OBJECT_0 + DATA_TIMER)
     196        {
     197            m->fTimerArmed = false;
     198            updateInfo();
     199        }
     200        else if (dwReady == WAIT_FAILED)
     201        {
     202            LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
     203            return VERR_INTERNAL_ERROR;
    164204        }
    165205        else
    166206        {
    167             if (dwReady == WAIT_FAILED)
    168                 LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
    169             else
    170                 LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
     207            LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
    171208            return VERR_INTERNAL_ERROR;
    172209        }
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