typedef struct _OVERLAPPED {

    DWORD Internal; // [out] 에러코드 ex> STATUS_PENDING 

    DWORD InternalHigh; [out] 전송된 바이트 수

    DWORD Offset; // [in] 32bit 하위 파일 오프셋

    DWORD OffsetHigh; // [in] 32bit 상위 파일 오프셋

    HANDLE hEvent; // [in] 이벤트 핸들이나 데이터

} OVERLAPPED, *LPOVERLAPPED;


[in] 의 경우 ReadFile이나 WriteFile 호출 전에 초기화가 되어 있어야 한다. (일반적으로 0)

ex> OVERLAPPED o = {0};


#define HasOverlappedIoCompleted (pOverlapped) ( (pOverlapped)->Internal != STATUS_PENDING )

I/O 요청이 진행중인 경우 FALSE, 요청이 완료되었을 경우 TRUE를 반환한다. 


주의점

1. 디바이스 드라이버는 비동기 I/O 요청을 항상 FIFO 방식으로만 처리하지 않는다.

2. 비동기 I/O 요청을 시도하는 경우에라도 시스템이 알아서 동기 I/O로 처리하는 경우가 있다. 

(캐쉬에 있는 경우 이 요청이 디바이스 드라이버의 요청 목록에 삽입이 되지 않는다.)

3. ReadFile과 WriteFile은 I/O 요청이 동기적으로 수행되는 경우 0이 아닌 값 (TRUE) 을 반환한다.

I/O 요청이 비동기적으로 수행되는 경우나 에러가 발생하는 경우 FALSE를 반환한다.

 ERROR_IO_PENDING

 성공. I/O 요청이 디바이스 요청 목록에 삽입이 완료 되었다 라는 의미.

 ERROR_INVALID_USER_BUFFER

 ERROR_NOT_ENOUGH_MEMORY

 요청 목록이 꽉 찬 경우에 발생

 ERROR_NOT_ENOUGH_QUATA

 I/O 요청을 기다리는 동안 사용자가 전달한 버퍼를 잠그지 못한 경우

 4. 데이터 버퍼와 OVERLAPPED 구조체는 I/O 요청이 완료될 때 까지 옮겨지거나 삭제되지 않아야 한다.

( 때문에 매 I/O 요청마다 새로운 OVERLAPPED 구조체를 생성하고 초기화 해야 한다. )


함수가 반환되면 스레드 스택에 있는 b와 o가 삭제된다. 디바이스 드라이버가 함수가 반환된 후 

두 개의 변수에 접근을 하는 순간 AV이 발생할 것이다. 


VOID Foo (HANDLE hFile) { 

    OVERLAPPED o = { 0 }; 

    BYTE b[100]; 

    ReadFile (hFile, b, 100, NULL, &o); 

}


※ I/O 작업의 취소

1. BOOL CancelIo(HANDLE hFile); => 이 함수를 호출한 스레드가 삽입한 모든 I/O을 취소한다.

2. 모든 스레드의 모든 I/O를 완전히 취소하고 싶다면 장치에 대한 핸들을 닫으면 된다. 

3. BOOL CancelIoEx (HANDLE hFile, LPOVERLAPPED pOverlapped); => 하나의 I/O 요청만을 취소한다. 

(이 함수를 호출한 스레드의 I/O요청뿐 아니라 다른 스레드가 삽입한 I/O 요청도 취소할 수 있다.

pOverlapped에 NULL을 전달하면 hFile이 가리키는 장치에 대한 모든 I/O요청을 취소한다.)

 

'개발지식창고 > Serial통신' 카테고리의 다른 글

비동기 I/O 요청에 대한 완료 통지의 수신  (0) 2011.12.19
Overlapped I/O (2)  (0) 2011.12.19
Overlapped I/O (1)  (0) 2011.12.19
Serial 통신 Cycle  (0) 2011.11.30
Posted by 모과이IT
,