1
0
forked from 0ad/0ad

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:
janwas 2004-08-17 13:40:55 +00:00
parent af85086e3b
commit a8b8471a23
2 changed files with 42 additions and 43 deletions

View File

@ -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");

View File

@ -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