no longer require aiocb to be zeroed (real aio doesn't).
removed user-visible pointer in aiocb; cb -> req mapping is now better. This was SVN commit r1010.
This commit is contained in:
parent
af85086e3b
commit
a8b8471a23
@ -186,7 +186,13 @@ struct Req
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// TODO: explain links between Req and cb
|
// an aiocb is used to pass the request from caller to aio,
|
||||||
|
// and serves as a "token" identifying the IO - its address is unique.
|
||||||
|
// Req holds some state needed for the Windows AIO calls (OVERLAPPED).
|
||||||
|
//
|
||||||
|
// cb -> req (e.g. in aio_return) is accomplished by searching reqs
|
||||||
|
// for the given cb (no problem since MAX_REQS is small).
|
||||||
|
// req -> cb via Req.cb pointer.
|
||||||
|
|
||||||
|
|
||||||
const int MAX_REQS = 16;
|
const int MAX_REQS = 16;
|
||||||
@ -221,34 +227,40 @@ static void req_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Req* req_alloc(aiocb* cb)
|
// return first Req with given cb field
|
||||||
|
// (may be 0; useful if searching for a free Req)
|
||||||
|
static Req* req_find(const aiocb* cb)
|
||||||
{
|
{
|
||||||
Req* r = reqs;
|
Req* r = reqs;
|
||||||
for(int i = 0; i < MAX_REQS; i++, r++)
|
for(int i = 0; i < MAX_REQS; i++, r++)
|
||||||
if(r->cb == 0)
|
if(r->cb == cb)
|
||||||
{
|
goto found;
|
||||||
r->cb = cb;
|
|
||||||
cb->req_ = r;
|
r = 0; // not found
|
||||||
|
found:
|
||||||
|
|
||||||
|
#ifdef PARANOIA
|
||||||
|
debug_out("req_find cb=%p r=%p\n", cb, r);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Req* req_alloc(aiocb* cb)
|
||||||
|
{
|
||||||
|
assert(cb);
|
||||||
|
|
||||||
|
// first free Req, or 0
|
||||||
|
Req* r = req_find(0);
|
||||||
|
if(r)
|
||||||
|
r->cb = cb;
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
debug_out("req_alloc cb=%p r=%p\n", cb, r);
|
debug_out("req_alloc cb=%p r=%p\n", cb, r);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Req* req_find(const aiocb* cb)
|
|
||||||
{
|
|
||||||
#ifdef PARANOIA
|
|
||||||
debug_out("req_find cb=%p r=%p\n", cb, cb->req_);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (Req*)cb->req_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -258,13 +270,7 @@ static int req_free(Req* r)
|
|||||||
debug_out("req_free cb=%p r=%p\n", r->cb, r);
|
debug_out("req_free cb=%p r=%p\n", r->cb, r);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(r->cb == 0)
|
assert(r->cb != 0 && "req_free: not currently in use");
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->cb->req_ = 0;
|
|
||||||
r->cb = 0;
|
r->cb = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -439,18 +445,11 @@ debug_out("aio_rw cb=%p\n", cb);
|
|||||||
|
|
||||||
WIN_SAVE_LAST_ERROR;
|
WIN_SAVE_LAST_ERROR;
|
||||||
|
|
||||||
const bool is_write = cb->aio_lio_opcode == LIO_WRITE;
|
// no-op from lio_listio
|
||||||
|
if(!cb || cb->aio_lio_opcode == LIO_NOP)
|
||||||
if(!cb)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if(cb->aio_lio_opcode == LIO_NOP)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
const bool is_write = cb->aio_lio_opcode == LIO_WRITE;
|
||||||
|
|
||||||
HANDLE h = aio_h_get(cb->aio_fildes);
|
HANDLE h = aio_h_get(cb->aio_fildes);
|
||||||
if(h == INVALID_HANDLE_VALUE)
|
if(h == INVALID_HANDLE_VALUE)
|
||||||
@ -459,7 +458,7 @@ debug_out("aio_rw cb=%p\n", cb);
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cb->req_)
|
if(req_find(cb))
|
||||||
{
|
{
|
||||||
// SUSv3 says this has undefined results; we fail the attempt.
|
// SUSv3 says this has undefined results; we fail the attempt.
|
||||||
debug_warn("aio_rw: aiocb is already in use");
|
debug_warn("aio_rw: aiocb is already in use");
|
||||||
@ -628,7 +627,10 @@ debug_out("aio_return cb=%p\n", cb);
|
|||||||
|
|
||||||
Req* const r = req_find(cb);
|
Req* const r = req_find(cb);
|
||||||
if(!r)
|
if(!r)
|
||||||
|
{
|
||||||
|
debug_warn("aio_return: cb not found (already called aio_return?)");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
assert(r->ovl.Internal == 0 && "aio_return with transfer in progress");
|
assert(r->ovl.Internal == 0 && "aio_return with transfer in progress");
|
||||||
|
|
||||||
|
@ -33,9 +33,6 @@ struct aiocb
|
|||||||
int aio_reqprio; // Request priority offset.
|
int aio_reqprio; // Request priority offset.
|
||||||
struct sigevent aio_sigevent; // Signal number and value.
|
struct sigevent aio_sigevent; // Signal number and value.
|
||||||
int aio_lio_opcode; // Operation to be performed.
|
int aio_lio_opcode; // Operation to be performed.
|
||||||
|
|
||||||
// internal
|
|
||||||
void* req_; // != 0 <==> cb in use
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
Loading…
Reference in New Issue
Block a user