Implement overlapped completion routines.

Don't use lpOverlapped->OffsetHigh to store bytes to transfer.
oldstable
Mike McCormack 2001-07-12 22:29:41 +00:00 committed by Alexandre Julliard
parent 1fc39be64f
commit e61ad3a9f3
4 changed files with 39 additions and 19 deletions

View File

@ -2912,6 +2912,8 @@ static BOOL COMM_WaitCommEvent(
ovp->func = COMM_WaitCommEventService;
ovp->buffer = (char *)lpdwEvents;
ovp->fd = fd;
ovp->count = 0;
ovp->completion_func = 0;
ovp->next = NtCurrentTeb()->pending_list;
ovp->prev = NULL;

View File

@ -1268,7 +1268,7 @@ static void FILE_AsyncReadService(async_private *ovp, int events)
/* check to see if the data is ready (non-blocking) */
result = read(ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh],
lpOverlapped->OffsetHigh - lpOverlapped->InternalHigh);
ovp->count - lpOverlapped->InternalHigh);
if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR)))
{
@ -1286,9 +1286,9 @@ static void FILE_AsyncReadService(async_private *ovp, int events)
}
lpOverlapped->InternalHigh += result;
TRACE("read %d more bytes %ld/%ld so far\n",result,lpOverlapped->InternalHigh,lpOverlapped->OffsetHigh);
TRACE("read %d more bytes %ld/%d so far\n",result,lpOverlapped->InternalHigh,ovp->count);
if(lpOverlapped->InternalHigh < lpOverlapped->OffsetHigh)
if(lpOverlapped->InternalHigh < ovp->count)
r = STATUS_PENDING;
else
r = STATUS_SUCCESS;
@ -1334,8 +1334,6 @@ BOOL WINAPI ReadFileEx(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
return FALSE;
}
overlapped->Offset = 0;
overlapped->OffsetHigh = bytesToRead; /* FIXME: wrong */
overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0;
@ -1375,6 +1373,8 @@ BOOL WINAPI ReadFileEx(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
return FALSE;
}
ovp->lpOverlapped = overlapped;
ovp->count = bytesToRead;
ovp->completion_func = lpCompletionRoutine;
ovp->timeout = timeout;
gettimeofday(&ovp->tv,NULL);
add_timeout(&ovp->tv,timeout);
@ -1463,7 +1463,7 @@ static void FILE_AsyncWriteService(struct async_private *ovp, int events)
/* write some data (non-blocking) */
result = write(ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh],
lpOverlapped->OffsetHigh-lpOverlapped->InternalHigh);
ovp->count-lpOverlapped->InternalHigh);
if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR)))
{
@ -1480,9 +1480,9 @@ static void FILE_AsyncWriteService(struct async_private *ovp, int events)
lpOverlapped->InternalHigh += result;
TRACE("wrote %d more bytes %ld/%ld so far\n",result,lpOverlapped->InternalHigh,lpOverlapped->OffsetHigh);
TRACE("wrote %d more bytes %ld/%d so far\n",result,lpOverlapped->InternalHigh,ovp->count);
if(lpOverlapped->InternalHigh < lpOverlapped->OffsetHigh)
if(lpOverlapped->InternalHigh < ovp->count)
r = STATUS_PENDING;
else
r = STATUS_SUCCESS;
@ -1510,8 +1510,6 @@ BOOL WINAPI WriteFileEx(HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
return FALSE;
}
overlapped->Offset = 0;
overlapped->OffsetHigh = bytesToWrite;
overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0;
@ -1545,6 +1543,8 @@ BOOL WINAPI WriteFileEx(HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
ovp->event = POLLOUT;
ovp->func = FILE_AsyncWriteService;
ovp->buffer = (LPVOID) buffer;
ovp->count = bytesToWrite;
ovp->completion_func = lpCompletionRoutine;
ovp->fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
if(ovp->fd <0)
{

View File

@ -43,6 +43,8 @@ typedef struct async_private
int event;
char *buffer;
async_handler func;
int count;
LPOVERLAPPED_COMPLETION_ROUTINE completion_func;
struct async_private *next;
struct async_private *prev;
} async_private;

View File

@ -44,8 +44,27 @@ static inline int time_before( struct timeval *t1, struct timeval *t2 )
((t1->tv_sec == t2->tv_sec) && (t1->tv_usec < t2->tv_usec)));
}
static void finish_async(async_private *ovp)
static void CALLBACK call_completion_routine(ULONG_PTR data)
{
async_private* ovp = (async_private*)data;
ovp->completion_func(ovp->lpOverlapped->Internal,
ovp->lpOverlapped->InternalHigh,
ovp->lpOverlapped);
ovp->completion_func=NULL;
HeapFree(GetProcessHeap(), 0, ovp);
}
static void finish_async(async_private *ovp, DWORD status)
{
ovp->lpOverlapped->Internal=status;
/* call ReadFileEx/WriteFileEx's overlapped completion function */
if(ovp->completion_func)
{
QueueUserAPC(call_completion_routine,GetCurrentThread(),(ULONG_PTR)ovp);
}
/* remove it from the active list */
if(ovp->prev)
ovp->prev->next = ovp->next;
@ -60,7 +79,7 @@ static void finish_async(async_private *ovp)
close(ovp->fd);
NtSetEvent(ovp->lpOverlapped->hEvent,NULL);
HeapFree(GetProcessHeap(), 0, ovp);
if(!ovp->completion_func) HeapFree(GetProcessHeap(), 0, ovp);
}
/***********************************************************************
@ -96,15 +115,13 @@ static void check_async_list(void)
if(ovp->lpOverlapped->Internal!=STATUS_PENDING)
{
ovp->lpOverlapped->Internal=STATUS_UNSUCCESSFUL;
finish_async(ovp);
finish_async(ovp,STATUS_UNSUCCESSFUL);
continue;
}
if(ovp->timeout && time_before(&ovp->tv,&now))
{
ovp->lpOverlapped->Internal=STATUS_TIMEOUT;
finish_async(ovp);
finish_async(ovp,STATUS_TIMEOUT);
continue;
}
@ -135,8 +152,7 @@ static void check_async_list(void)
if( r==0 )
{
timeout_user->lpOverlapped->Internal = STATUS_TIMEOUT;
finish_async(timeout_user);
finish_async(timeout_user, STATUS_TIMEOUT);
continue;
}
@ -147,7 +163,7 @@ static void check_async_list(void)
user[i]->func(user[i],fds[i].revents);
if(user[i]->lpOverlapped->Internal!=STATUS_PENDING)
finish_async(user[i]);
finish_async(user[i],user[i]->lpOverlapped->Internal);
}
if(fds[0].revents == POLLIN)