def ThreadLoop(self, startupEvent): try: hDir = CreateFile( self.path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0) if hDir == INVALID_HANDLE_VALUE: self.startException = FormatError() startupEvent.set() return overlapped = OVERLAPPED() overlapped.hEvent = CreateEvent(None, 1, 0, None) buffer = (c_byte * BUFSIZE)() events = (HANDLE * 2)(overlapped.hEvent, self.stopEvent) flags = (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SECURITY) includeSubdirs = self.includeSubdirs renamePath = None bytesReturned = DWORD() noneCallback = cast(None, LPOVERLAPPED_COMPLETION_ROUTINE) startupEvent.set() while 1: ReadDirectoryChangesW(hDir, buffer, BUFSIZE, includeSubdirs, flags, byref(bytesReturned), byref(overlapped), noneCallback) rc = MsgWaitForMultipleObjects(2, events, 0, INFINITE, QS_ALLINPUT) if rc == WAIT_OBJECT_0: res = GetOverlappedResult(hDir, byref(overlapped), byref(bytesReturned), 1) address = addressof(buffer) while True: fni = FILE_NOTIFY_INFORMATION.from_address(address) length = fni.FileNameLength / WCHAR_SIZE fileName = wstring_at(address + 12, length) action = fni.Action fullFilename = os.path.join(self.path, fileName) if action == FILE_ACTION_ADDED: self.TriggerEvent("Created", (fullFilename, )) elif action == FILE_ACTION_REMOVED: self.TriggerEvent("Deleted", (fullFilename, )) elif action == FILE_ACTION_MODIFIED: self.TriggerEvent("Updated", (fullFilename, )) elif action == FILE_ACTION_RENAMED_OLD_NAME: renamePath = fullFilename elif action == FILE_ACTION_RENAMED_NEW_NAME: self.TriggerEvent("Renamed", (renamePath, fullFilename)) renamePath = None if fni.NextEntryOffset == 0: break address += fni.NextEntryOffset elif rc == WAIT_OBJECT_0 + 1: break CloseHandle(hDir) except: self.thread = None raise
def __DoOneEvent(self): try: resultCode = MsgWaitForMultipleObjects(1, self.__events, 0, 10000, QS_ALLINPUT) if resultCode == WAIT_OBJECT_0: while 1: try: action = self.__queue.popleft() except IndexError: break try: self.HandleAction(action) except: action.PrintUnhandledException() finally: # if the frame reference would not be removed, the # action would never be garbage collected. action.callersFrame = None elif resultCode == WAIT_OBJECT_0 + 1: self.__PumpWaitingMessages() elif resultCode == WAIT_TIMEOUT: # Our timeout has elapsed. self.Poll() else: raise RuntimeError("unexpected win32wait return value") except: eg.PrintDebugNotice("Exception in __DoOneEvent") eg.PrintTraceback()
def ReceiveThreadProc(self): hFile = self.hFile osReader = self.osReader lpBuf = create_string_buffer(1) dwRead = DWORD() pHandles = (HANDLE * 2)(osReader.hEvent, self.stopEvent) waitingOnRead = False while self.keepAlive: #print "ReceiveThreadProc" # if no read is outstanding, then issue another one if not waitingOnRead: #print "ResetEvent" ResetEvent(osReader.hEvent) returnValue = self._ReadFile( hFile, lpBuf, 1, # we want to get notified as soon as a byte is available byref(dwRead), byref(osReader) ) if not returnValue: err = GetLastError() if err != 0 and err != ERROR_IO_PENDING: raise SerialError() waitingOnRead = True else: # read completed immediately if dwRead.value: self.HandleReceive(lpBuf.raw) continue ret = MsgWaitForMultipleObjects( 2, pHandles, 0, 100000, QS_ALLINPUT ) if ret == WAIT_OBJECT_0: returnValue = GetOverlappedResult( hFile, byref(osReader), byref(dwRead), 0 ) #print "GetOverlappedResult", returnValue, dwRead.value waitingOnRead = False if returnValue and dwRead.value: self.HandleReceive(lpBuf.raw) elif ret == WAIT_OBJECT_0 + 1: #print "WAIT_OBJECT_1" # stop event signaled self.readCondition.acquire() self.readCondition.notifyAll() self.readCondition.release() break elif ret == WAIT_TIMEOUT: #print "WAIT_TIMEOUT" pass else: raise SerialError("Unknown message in ReceiveThreadProc")
def WaitOnEvent(self, event, timeout=10): endTime = clock() + timeout events = (HANDLE * 1)(event) while self.__alive: resultCode = MsgWaitForMultipleObjects(1, events, 0, int(timeout * 1000), QS_ALLINPUT) if resultCode == WAIT_OBJECT_0: return True elif resultCode == WAIT_TIMEOUT: # Timeout expired. return # must be a message. self.__PumpWaitingMessages() timeout = endTime - clock() if timeout < 0: return True
def Wait(self, timeout): endTime = clock() + timeout events = (HANDLE * 1)(self.__dummyEvent) while True: resultCode = MsgWaitForMultipleObjects(1, events, 0, int(timeout * 1000), QS_ALLINPUT) if resultCode == WAIT_OBJECT_0: # event signaled - should never happen! raise Exception("Got unknown event in ThreadWorker.Wait()") elif resultCode == WAIT_TIMEOUT: # Timeout expired. return # must be a message. self.__PumpWaitingMessages() timeout = endTime - clock() if timeout < 0: return