void disk_engine::start_io(aio_task_ptr& aio_tsk) { auto aio = aio_tsk->aio(); aio->engine = this; { auto_lock<::dsn::utils::ex_lock_nr> l(_lock); if (!_is_running) { aio_tsk->enqueue(ERR_SERVICE_NOT_FOUND, 0, _node); return; } _request_count++; } // TODO: profiling, throttling here if (aio_tsk->spec().on_aio_call.execute(task::get_current_task(), aio_tsk.get(), true)) { aio_tsk->add_ref(); return _provider->aio(aio_tsk); } else { aio_tsk->enqueue(ERR_FILE_OPERATION_FAILED, 0, _node); } }
error_code native_win_aio_provider::aio_internal(aio_task_ptr& aio_tsk, bool async, __out_param uint32_t* pbytes /*= nullptr*/) { auto aio = (windows_disk_aio_context*)aio_tsk->aio().get(); BOOL r = FALSE; aio->olp.Offset = (uint32_t)aio->file_offset; aio->olp.OffsetHigh = (uint32_t)(aio->file_offset >> 32); if (!async) { aio->evt = new utils::notify_event(); aio->err = ERR_OK; aio->bytes = 0; } switch (aio->type) { case AIO_Read: r = ::ReadFile(aio->file, aio->buffer, aio->buffer_size, NULL, &aio->olp); break; case AIO_Write: r = ::WriteFile(aio->file, aio->buffer, aio->buffer_size, NULL, &aio->olp); break; default: dassert (false, "unknown aio type %u", static_cast<int>(aio->type)); break; } if (!r) { int err = ::GetLastError(); if (err != ERROR_IO_PENDING) { derror("file operation failed, err = %u", err); if (async) { complete_io(aio_tsk, ERR_FILE_OPERATION_FAILED, 0); } else { delete aio->evt; aio->evt = nullptr; } return ERR_FILE_OPERATION_FAILED; } } if (async) { return ERR_IO_PENDING; } else { aio->evt->wait(); delete aio->evt; aio->evt = nullptr; *pbytes = aio->bytes; return aio->err; } }
void disk_engine::write(aio_task_ptr& aio) { aio->aio()->type = AIO_Write; return start_io(aio); }
void disk_engine::read(aio_task_ptr& aio) { aio->aio()->type = AIO_Read; return start_io(aio); }