예제 #1
0
// wait for events to occur, read them and send to interested parties
// returns false it empty status was read, which means we whould exit
//         true otherwise
bool wxIOCPThread::ReadEvents()
{
    unsigned long count = 0;
    wxFSWatchEntryMSW* watch = NULL;
    OVERLAPPED* overlapped = NULL;
    if (!m_iocp->GetStatus(&count, &watch, &overlapped))
        return true; // error was logged already, we don't want to exit

    // this is our exit condition, so we return false
    if (!count && !watch && !overlapped)
        return false;

    // in case of spurious wakeup
    if (!count || !watch)
        return true;

    wxLogTrace( wxTRACE_FSWATCHER, "[iocp] Read entry: path='%s'",
                watch->GetPath());

    // First check if we're still interested in this watch, we could have
    // removed it in the meanwhile.
    if ( m_iocp->CompleteRemoval(watch) )
        return true;

    // extract events from buffer info our vector container
    wxVector<wxEventProcessingData> events;
    const char* memory = static_cast<const char*>(watch->GetBuffer());
    int offset = 0;
    do
    {
        const FILE_NOTIFY_INFORMATION* e =
              static_cast<const FILE_NOTIFY_INFORMATION*>((const void*)memory);

        events.push_back(wxEventProcessingData(e, watch));

        offset = e->NextEntryOffset;
        memory += offset;
    }
    while (offset);

    // process events
    ProcessNativeEvents(events);

    // reissue the watch. ignore possible errors, we will return true anyway
    (void) m_service->SetUpWatch(*watch);

    return true;
}
예제 #2
0
// wait for events to occur, read them and send to interested parties
// returns false it empty status was read, which means we whould exit
//         true otherwise
bool wxIOCPThread::ReadEvents()
{
    unsigned long count = 0;
    wxFSWatchEntryMSW* watch = NULL;
    OVERLAPPED* overlapped = NULL;
    switch ( m_iocp->GetStatus(&count, &watch, &overlapped) )
    {
        case wxIOCPService::Status_OK:
            break; // nothing special to do, continue normally

        case wxIOCPService::Status_Error:
            return true; // error was logged already, we don't want to exit

        case wxIOCPService::Status_Deleted:
            {
                wxFileSystemWatcherEvent
                    removeEvent(wxFSW_EVENT_DELETE,
                                watch->GetPath(),
                                wxFileName());
                SendEvent(removeEvent);
            }

            // It isn't useful to continue watching this directory as it
            // doesn't exist any more -- and even recreating a directory with
            // the same name still wouldn't resume generating events for the
            // existing wxIOCPService, so it's useless to continue.
            return false;

        case wxIOCPService::Status_Exit:
            return false; // stop reading events
    }

    // if the thread got woken up but we got an empty packet it means that
    // there was an overflow, too many events and not all could fit in
    // the watch buffer.  In this case, ReadDirectoryChangesW dumps the
    // buffer.
    if (!count && watch)
    {
         wxLogTrace(wxTRACE_FSWATCHER, "[iocp] Event queue overflowed: path=\"%s\"",
                    watch->GetPath());

        if (watch->GetFlags() & wxFSW_EVENT_WARNING)
        {
            wxFileSystemWatcherEvent
                overflowEvent(wxFSW_EVENT_WARNING, wxFSW_WARNING_OVERFLOW);
            overflowEvent.SetPath(watch->GetPath());
            SendEvent(overflowEvent);
        }

        // overflow is not a fatal error, we still want to get future events
        // reissue the watch
        (void) m_service->SetUpWatch(*watch);
        return true;
    }

    // in case of spurious wakeup
    if (!count || !watch)
        return true;

    wxLogTrace( wxTRACE_FSWATCHER, "[iocp] Read entry: path='%s'",
                watch->GetPath());

    // First check if we're still interested in this watch, we could have
    // removed it in the meanwhile.
    if ( m_iocp->CompleteRemoval(watch) )
        return true;

    // extract events from buffer info our vector container
    wxVector<wxEventProcessingData> events;
    const char* memory = static_cast<const char*>(watch->GetBuffer());
    int offset = 0;
    do
    {
        const FILE_NOTIFY_INFORMATION* e =
              static_cast<const FILE_NOTIFY_INFORMATION*>((const void*)memory);

        events.push_back(wxEventProcessingData(e, watch));

        offset = e->NextEntryOffset;
        memory += offset;
    }
    while (offset);

    // process events
    ProcessNativeEvents(events);

    // reissue the watch. ignore possible errors, we will return true anyway
    (void) m_service->SetUpWatch(*watch);

    return true;
}