1
0
forked from 0ad/0ad

aio_open_winhandle - open an existing windows handle for use with aio_* functions

This was SVN commit r57.
This commit is contained in:
Simon Brenner 2003-11-13 15:27:16 +00:00
parent 3dfeb3e5f8
commit b07baf71e3

View File

@ -18,13 +18,14 @@
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <cstdio>
#include <winsock2.h>
#include "posix.h" #include "posix.h"
#include "win.h" #include "win.h"
#include "misc.h" #include "misc.h"
#include "types.h" #include "types.h"
// Win32 functions require sector aligned transfers. // Win32 functions require sector aligned transfers.
// updated by aio_open; changes don't affect aio_return // updated by aio_open; changes don't affect aio_return
static u32 sector_size = 4096; static u32 sector_size = 4096;
@ -119,14 +120,18 @@ static void cleanup(void)
CloseHandle(reqs_mutex); CloseHandle(reqs_mutex);
} }
// called by aio_open and aio_open_winhandle
// called by first aio_open
static void init() static void init()
{ {
for(int i = 0; i < MAX_REQS; i++) ONCE(
reqs[i].ovl.hEvent = CreateEvent(0,1,0,0); // manual reset for(int i = 0; i < MAX_REQS; i++)
{
reqs[i].ovl.hEvent = CreateEvent(0,1,0,0); // manual reset
//printf("Req %p [%d]: hEvent %x\n", reqs+i, i, reqs[i].ovl.hEvent);
}
atexit(cleanup); atexit(cleanup);
)
} }
@ -141,14 +146,9 @@ int aio_close(int fd)
return 0; return 0;
} }
//NOTE: Requires that the "open" lock is held
// open fn in async mode; associate with fd (retrieve via aio_h(fd)) int alloc_handle_entry(int fd)
int aio_open(const char* fn, int mode, int fd)
{ {
LOCK(open)
ONCE(init())
// alloc aio_hs entry // alloc aio_hs entry
if((unsigned)fd >= hs_cap) if((unsigned)fd >= hs_cap)
{ {
@ -165,6 +165,34 @@ LOCK(open)
aio_hs = aio_hs2; aio_hs = aio_hs2;
hs_cap = hs_cap2; hs_cap = hs_cap2;
} }
return 0;
}
// fd is already opened in async/overlapped mode; add to required internal structures
int aio_open_winhandle(HANDLE fd)
{
init();
LOCK(open)
if (alloc_handle_entry(HANDLE2INT(fd)) == -1)
return -1;
aio_hs[HANDLE2INT(fd)]=fd;
UNLOCK(open)
return 0;
}
// open fn in async mode; associate with fd (retrieve via aio_h(fd))
int aio_open(const char* fn, int mode, int fd)
{
init();
LOCK(open)
if (alloc_handle_entry(fd) == -1)
return -1;
UNLOCK(open) UNLOCK(open)
@ -205,7 +233,6 @@ UNLOCK(open)
return 0; return 0;
} }
// called by aio_read, aio_write, and lio_listio // called by aio_read, aio_write, and lio_listio
// cb->aio_lio_opcode specifies desired operation // cb->aio_lio_opcode specifies desired operation
static int aio_rw(struct aiocb* cb) static int aio_rw(struct aiocb* cb)
@ -217,7 +244,10 @@ static int aio_rw(struct aiocb* cb)
HANDLE h = aio_h(cb->aio_fildes); HANDLE h = aio_h(cb->aio_fildes);
if(h == INVALID_HANDLE_VALUE) if(h == INVALID_HANDLE_VALUE)
{
printf("Invalid handle\n");
return -1; return -1;
}
LOCK(reqs) LOCK(reqs)
@ -226,41 +256,56 @@ LOCK(reqs)
if(!r) if(!r)
{ {
UNLOCK(reqs) UNLOCK(reqs)
printf("No Req\n");
return -1; return -1;
} }
r->cb = cb; r->cb = cb;
UNLOCK(reqs) UNLOCK(reqs)
unsigned long opt=0;
int optlen=sizeof(opt);
// align // align
r->pad = cb->aio_offset % sector_size; // offset to start of sector r->pad = cb->aio_offset % sector_size; // offset to start of sector
const u32 ofs = cb->aio_offset - r->pad; u32 ofs = cb->aio_offset - r->pad;
const u32 size = round_up((long)cb->aio_nbytes+r->pad, sector_size); u32 size = round_up((long)cb->aio_nbytes+r->pad, sector_size);
void* buf = cb->aio_buf; void* buf = cb->aio_buf;
const size_t _buf = (char*)buf - (char*)0; const size_t _buf = (char*)buf - (char*)0;
if(r->pad || _buf % sector_size) if (getsockopt((SOCKET)h, SOL_SOCKET, SO_TYPE, (char *)&opt, &optlen)==-1 &&
(WSAGetLastError()==WSAENOTSOCK))
{ {
// current align buffer is too small - resize if(r->pad || _buf % sector_size)
if(r->buf_size < size)
{ {
void* buf2 = realloc(r->buf, size); // current align buffer is too small - resize
if(!buf2) if(r->buf_size < size)
{
void* buf2 = realloc(r->buf, size);
if(!buf2)
return -1;
r->buf = buf2;
r->buf_size = size;
}
// unaligned writes are not supported -
// we'd have to read padding, then write our data. ugh.
if(cb->aio_lio_opcode == LIO_WRITE)
{
return -1; return -1;
r->buf = buf2; }
r->buf_size = size;
buf = r->buf;
} }
}
// unaligned writes are not supported - else
// we'd have to read padding, then write our data. ugh. {
if(cb->aio_lio_opcode == LIO_WRITE) ofs=0;
return -1; size=cb->aio_nbytes;
buf = r->buf;
} }
r->ovl.Offset = ofs; r->ovl.Offset = ofs;
u32 status = (cb->aio_lio_opcode == LIO_READ)? u32 status = (cb->aio_lio_opcode == LIO_READ)?
ReadFile(h, buf, size, 0, &r->ovl) : WriteFile(h, buf, size, 0, &r->ovl); ReadFile(h, buf, size, NULL, &r->ovl) : WriteFile(h, buf, size, NULL, &r->ovl);
if(status || GetLastError() == ERROR_IO_PENDING) if(status || GetLastError() == ERROR_IO_PENDING)
return 0; return 0;