Added method vfs_asynchronous_write_pages(), which, unsurprisingly,

writes the given page iovecs asynchronously. The new class
AsyncIOCallback is used to inform the caller when the request has been
finished.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27055 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-08-18 23:09:10 +00:00
parent 80048d7de3
commit 663948966c
2 changed files with 100 additions and 2 deletions

View File

@ -251,10 +251,44 @@ extern status_t _user_socketpair(int family, int type, int protocol,
extern status_t _user_get_next_socket_stat(int family, uint32 *cookie,
struct net_stat *stat);
/* vfs entry points... */
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
class AsyncIOCallback {
public:
virtual ~AsyncIOCallback();
virtual void IOFinished(status_t status,
bool partialTransfer,
size_t bytesTransferred) = 0;
void operator delete(void* address, size_t size);
static status_t IORequestCallback(void* data,
io_request* request, status_t status,
bool partialTransfer,
size_t transferEndOffset);
};
class StackableAsyncIOCallback : public AsyncIOCallback {
public:
StackableAsyncIOCallback(AsyncIOCallback* next);
protected:
AsyncIOCallback* fNextCallback;
};
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie,
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
uint32 flags, AsyncIOCallback* callback);
#endif // __cplusplus
#endif /* _KERNEL_VFS_H */

View File

@ -14,6 +14,44 @@
#endif
// #pragma mark - AsyncIOCallback
AsyncIOCallback::~AsyncIOCallback()
{
}
void
AsyncIOCallback::operator delete(void* address, size_t size)
{
io_request_free(address);
}
/* static */ status_t
AsyncIOCallback::IORequestCallback(void* data, io_request* request,
status_t status, bool partialTransfer, size_t transferEndOffset)
{
((AsyncIOCallback*)data)->IOFinished(status, partialTransfer,
transferEndOffset);
return B_OK;
}
// #pragma mark - StackableAsyncIOCallback
StackableAsyncIOCallback::StackableAsyncIOCallback(AsyncIOCallback* next)
:
fNextCallback(next)
{
}
// #pragma mark -
struct iterative_io_cookie {
struct vnode* vnode;
file_descriptor* descriptor;
@ -379,6 +417,32 @@ vfs_synchronous_io(io_request* request,
}
status_t
vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie, off_t pos,
const iovec* vecs, size_t count, size_t numBytes, uint32 flags,
AsyncIOCallback* callback)
{
IORequest* request = IORequest::Create((flags & B_VIP_IO_REQUEST) != 0);
if (request == NULL) {
callback->IOFinished(B_NO_MEMORY, true, 0);
return B_NO_MEMORY;
}
status_t status = request->Init(pos, vecs, count, numBytes, true,
flags | B_DELETE_IO_REQUEST);
if (status != B_OK) {
delete request;
callback->IOFinished(status, true, 0);
return status;
}
request->SetFinishedCallback(&AsyncIOCallback::IORequestCallback,
callback);
return vfs_vnode_io(vnode, cookie, request);
}
// #pragma mark - public API