Example #1
0
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);
    }
}
Example #2
0
void disk_engine::complete_io(aio_task_ptr& aio, error_code err, uint32_t bytes, int delay_milliseconds)
{
    // TODO: failure injection, profiling, throttling

    if (err != ERR_OK)
    {
        dwarn(
                    "disk operation failure with code %s, err = 0x%x, aio task id = %llx",
                    aio->spec().name,
                    err.get(),
                    aio->id()
                    );
    }
    
    {
        auto_lock<::dsn::utils::ex_lock_nr> l(_lock);
        _request_count--;
    }
    
    aio->enqueue(err, bytes, _node);
    aio->release_ref();
}
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;
    }
}
Example #4
0
void disk_engine::write(aio_task_ptr& aio)
{
    aio->aio()->type = AIO_Write;
    return start_io(aio);
}
Example #5
0
void disk_engine::read(aio_task_ptr& aio)
{
    aio->aio()->type = AIO_Read;    
    return start_io(aio);
}