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 |