示例#1
0
bool CReaderWriterLockNonReentrance::AcquireWriterLock(DWORD dwTimeout)
{
    bool blCanWrite ;

    EnterCS();
    if(0 == (m_iNumOfWriter | m_iNumOfReaderEntered))
    {
        ++m_iNumOfWriter;
        blCanWrite = TRUE;
    }
    else if(0 == dwTimeout)
    {
        blCanWrite = FALSE;
    }
    else
    {
        blCanWrite = _WriterWaitAndLeaveCSIfSuccess(dwTimeout);
        if(blCanWrite)
        {
            return TRUE;
        }
    }

    LeaveCS();
    return blCanWrite;
}
示例#2
0
bool CReaderWriterLockNonReentrance::_WriterWaitAndLeaveCSIfSuccess(DWORD dwTimeout)
{
    //EnterCS();
    _ASSERT(0 != dwTimeout);

    // Increase Writer-counter & reset Reader-event if necessary
    INT _iNumOfWriter = ++m_iNumOfWriter;
    if(	(1 == _iNumOfWriter) && (NULL != m_hSafeToReadEvent) )
    {
        ResetEvent(m_hSafeToReadEvent);
    }

    if(NULL == m_hSafeToWriteEvent)
    {
        m_hSafeToWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    }
    LeaveCS();

    bool blCanWrite = (WAIT_OBJECT_0 == WaitForSingleObject(m_hSafeToWriteEvent, dwTimeout));
    if(FALSE == blCanWrite)
    {
        // Undo what we changed after timeout
        EnterCS();
        if(0 == --m_iNumOfWriter)
        {
            CloseHandle(m_hSafeToWriteEvent);
            m_hSafeToWriteEvent = NULL;

            if(0 == m_iNumOfReaderEntered)
            {
                // Although it was timeout, it's still safe to be writer now
                ++m_iNumOfWriter;
                LeaveCS();
                blCanWrite = TRUE;
            }
            else if(m_hSafeToReadEvent)
            {
                SetEvent(m_hSafeToReadEvent);
            }
        }
    }
    return blCanWrite;
}
示例#3
0
bool CReaderWriterLockNonReentrance::_UpgradeToWriterLockAndLeaveCS(DWORD dwTimeout) throw()
{
    _ASSERT(m_iNumOfReaderEntered > 0);

    if(0 == dwTimeout)
    {
        LeaveCS();
        return FALSE;
    }

    --m_iNumOfReaderEntered;
    bool blCanWrite = _WriterWaitAndLeaveCSIfSuccess(dwTimeout);
    if(FALSE == blCanWrite)
    {
        // Now analyze why it was failed to have suitable action
        if(0 == m_iNumOfWriter)
        {
            _ASSERT(0 < m_iNumOfReaderEntered);
            // There are some readers still owning the lock
            // It's safe to be a reader again after failure
            ++m_iNumOfReaderEntered;
        }
        else
        {
            // Reach to here, it's NOT safe to be a reader immediately
            _ReaderWait(INFINITE);
            if(1 == m_iNumOfReaderEntered)
            {
                // After wait, now it's safe to be writer
                _ASSERT(0 == m_iNumOfWriter);
                m_iNumOfReaderEntered = 0;
                m_iNumOfWriter = 1;
                blCanWrite = TRUE;
            }
        }
        LeaveCS();
    }

    return blCanWrite;
}
示例#4
0
文件: events.c 项目: berkus/nemesis
bool_t EventDeliver( WSSvr_st *st, WSSvr_Window *w, WS_Event *ev, bool_t block) 
{
    Event_Val val;

    if(w->wid == ROOT_WINDOW) {
	HandleRootWindowEvent(st, ev);
    }
 
    ev->w = w->wid;

    if((!block) || (Pvs(thd) == st->event_thread)) {
	/* We can't block here, so optionally throw this event away */
	Threads$EnterCS(Pvs(thds), False);
	val = SQ_READ(st->free_event_sq);

	if(EC_READ(st->free_event_ec) < val) {

	    /* We would have to block - refuse the event */
	    Threads$LeaveCS(Pvs(thds));
	    return False;
	} else {
	    val = SQ_TICKET(st->free_event_sq);
	    Threads$LeaveCS(Pvs(thds));
	}
    } else {

	val = SQ_TICKET(st->free_event_sq);
    }

    EC_AWAIT(st->free_event_ec, val);
    
    val = val % NUM_EVENT_RECS;
    st->events[val] = *ev;
    
    EC_ADVANCE(st->valid_event_ec, 1);
    
    return True;
}
示例#5
0
bool CReaderWriterLockNonReentrance::AcquireReaderLock(DWORD dwTimeout)
{
    bool blCanRead;

    EnterCS();
    if(0 == m_iNumOfWriter)
    {
        // Enter successful without wait
        ++m_iNumOfReaderEntered;
        blCanRead = TRUE;
    }
    else
    {
        blCanRead = (dwTimeout)? _ReaderWait(dwTimeout) : FALSE;
    }
    LeaveCS();

    return blCanRead;
}
示例#6
0
文件: events.c 项目: berkus/nemesis
void EventThread(WSSvr_st *st) {

    Event_Val val = 0;
    
    WS_Event *ev;
    
    st->event_thread = Pvs(thd);
    while(1) {

	WSSvr_Window *w;

	EC_AWAIT(st->valid_event_ec, val + 1);
	ev = &st->events[val % NUM_EVENT_RECS];

	w = &st->window[ev->w];

	if(ev->d.tag == WS_EventType_Expose) {
	    /* Get the exposure rectangle */
	    Threads$EnterCS(Pvs(thds), False);
	    ev->d.u.Expose = w->expose_rect;
	    w->expose_due = False;
	    Threads$LeaveCS(Pvs(thds));
	}

	if(ev->d.tag == WS_EventType_Mouse) {

	    /* Try coalescing mouse events */
	    
	    while(EC_READ(st->valid_event_ec) > (val+1)) {
		WS_Event *ev_next;
		val++;
		
		ev_next = &st->events[val % NUM_EVENT_RECS];
		
		/* See if this is a mouse event in the same window */
		if((ev_next->d.tag == WS_EventType_Mouse) && 
		   (ev_next->d.u.Mouse.buttons == ev->d.u.Mouse.buttons)) {
		    
		    /* Free old event */
		    EC_ADVANCE(st->free_event_ec, 1);
		    
		    /* Point at new event */
		    ev = ev_next;
		} else {
		    /* Push this event back */
		    val--;
		    break;
		}
	    }
	}

	WM$HandleEvent(st->wm, ev, w->owner ? (&w->owner->wsf_cl) : NULL);
	
	/* Free event */
	EC_ADVANCE(st->free_event_ec, 1);
	
	val++;
#if 0
	if(st->need_refocus) {
	    MU_LOCK(&st->mu);
	    Refocus(st);
	    MU_RELEASE(&st->mu);
	}
#endif

    }
	
}
示例#7
0
bool CReaderWriterLockNonReentrance::_ReaderWait(DWORD dwTimeout) throw()
{
    bool blCanRead;

    ++m_iNumOfReaderWaiting;
    if(NULL == m_hSafeToReadEvent)
    {
        m_hSafeToReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    }

    if(INFINITE == dwTimeout) // INFINITE is a special value
    {
        do
        {
            LeaveCS();
            WaitForSingleObject(m_hSafeToReadEvent, INFINITE);
            // There might be one or more Writers entered, that's
            // why we need DO-WHILE loop here
            EnterCS();
        }
        while(0 != m_iNumOfWriter);

        ++m_iNumOfReaderEntered;
        blCanRead = TRUE;
    }
    else
    {
        LeaveCS();

        DWORD const dwBeginTime = GetTickCount();
        DWORD dwConsumedTime = 0;

        while(TRUE)
        {
            blCanRead = (WAIT_OBJECT_0 == WaitForSingleObject(m_hSafeToReadEvent,
                dwTimeout - dwConsumedTime));

            EnterCS();

            if(0 == m_iNumOfWriter)
            {
                // Regardless timeout or not, there is no Writer
                // So it's safe to be Reader right now
                ++m_iNumOfReaderEntered;
                blCanRead = TRUE;
                break;
            }

            if(FALSE == blCanRead)
            {
                // Timeout after waiting
                break;
            }

            // There are some Writers have just entered
            // So leave CS and prepare to try again
            LeaveCS();

            dwConsumedTime = GetTickCount() - dwBeginTime;
            if(dwConsumedTime > dwTimeout)
            {
                // Don't worry why the code here looks stupid
                // Because this case rarely happens, it's better
                //  to optimize code for the usual case
                blCanRead = FALSE;
                EnterCS();
                break;
            }
        }
    }

    if(0==--m_iNumOfReaderWaiting)
    {
        CloseHandle(m_hSafeToReadEvent);
        m_hSafeToReadEvent = NULL;
    }

    return blCanRead;
}
示例#8
0
void CReaderWriterLockNonReentrance::DowngradeFromWriterLock()
{
    EnterCS();
    _WriterRelease(TRUE);
    LeaveCS();
}
示例#9
0
void CReaderWriterLockNonReentrance::ReleaseWriterLock()
{
    EnterCS();
    _WriterRelease(FALSE);
    LeaveCS();
}
示例#10
0
void CTemporaryCS::EnterCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
	LeaveCS();
	cs->Enter();
	m_cs = cs;
}
示例#11
0
CTemporaryCS::~CTemporaryCS()
{
	LeaveCS();
}