aio_open_winhandle - open an existing windows handle for use with aio_* functions
This was SVN commit r57.
This commit is contained in:
parent
3dfeb3e5f8
commit
b07baf71e3
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user