Boost logo

Boost :

From: Roland (roland.schwarz_at_[hidden])
Date: 2004-01-01 08:40:26


(Michael Glassford <glassfordm_at_[hidden]>) wrote:

> > Should I simply unlock the mutex before entering WaitForMultipleObjects?
>
> It's hard to say without knowing what exactly the mutex is protecting.
> Perhaps you could post some sample code?
>

Ok I will try to pull something out of my developement code.

> > There is no user accessible API for such an operation.

Oh thank you, I somehow overlocked this fact. Using this I´ll post the following code.
(Which is a blocking, but cancelable write function.)
Say you have a port object, whose functions are protected by a monitor.
(This is for the Windows API.)

size_t tcp_port::write(const byte* p, size_t c)
{
DWORD dw;
MSG msg;
HANDLE rgev[2];
DWORD ev;
    
    lock lk(monitor);
    
    if (!WriteFile(m_h, p, c, &dw, &m_ovWrite)) {
        if (ERROR_IO_PENDING == GetLastError()) {
            regev[0] = m_evWrite;
            regev[1] = m_evCancel;
            while (TRUE) {

               // the following three lines are meant to be similar to the call of the wait function of a condition
                lk.unlock(); // Note 1
                ev = MsgWaitForMultipleObjects(2, rgev, FALSE, INFINITE, QS_ALLINPUT);
                lk.lock(); // Note 2

                if (WAIT_OBJECT_0 == ev) {
                    if (!GetOverlappedResult(m_h, &ovWrite, &dw, TRUE))
                        return 0;
                    else
                        break;
                } else if (WAIT_OBJECT_0+1 == ev) {
                    CancelIo(m_h);
                    return 0;
                }
                ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
            }
        }
       else
            retirn 0
    }
    *((unsigned __int64*)&(m_ovWrite.Offset)) += dw;
    return dw;
}

What I am beeing afraid is nopw, is that places "Note1" and "Note2" might introduce a race condition,
when another call to my port object goes in between. As far as I can understand, this normally is
avoided through the while loop that belongs to the "condition variable pattern".

Since such blocking calls to the operating system are similar in semantics to "cond.wait(lk)" (aren't they?)
I was looking for some systematic way to handle them in a similar way. I also think that using the library
to write platform independent code, it will be necessary to deal with this question at the lowest level possible
to avoid a lot of #ifdefs later on. Ideally I would like to see much less WinAPI calls in my function than I do now.

I am still not sure if I was able to expain my point, but I hope you will be patient enough
to ask me further questions that will help me to be more precise.

Roland


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk