libuv - свободный буфер записи - PullRequest
1 голос
/ 19 октября 2019

Документация для uv_write состояний [ 1 ]:

Примечание Память, на которую указывают буферы, должна оставаться действительной до получения обратного вызованазывается. Это также верно для uv_write2 ().

Таким образом, для базы буфера может потребоваться динамическое распределение. Вызывающая функция может выглядеть следующим образом:

void write_to_stream(uv_stream_t* stream) {   
    uv_write_t* write_req = new uv_write_t;
    uv_buf_t buf{};
    buf.base = new char[1024];
    buf.len = 1024;
    // fill the buffer
    uv_write(write_req, stream, buf, 1, on_write);
}

В этом случае память, выделенная new char[1024], должна быть действительной до тех пор, пока не будет запущен обратный вызов on_write.

Просмотрподпись обратного вызова void on_write(uv_write_t* req, int status) неочевидно, как освободить эту память, поскольку, похоже, нет способа получить доступ к этому указателю из обратного вызова.

void on_write(uv_write_t* req, int status) {
    // how to find the memory allocated for req's buffer?
    delete[] ???;
}

Каков предполагаемый способ освобождения этой памяти один разэто больше не нужно?

Ответы [ 2 ]

1 голос
/ 14 ноября 2019

Другой способ сделать это - использовать data. Обратите внимание, что все уф-ручки содержат поле data, которое можно использовать для своих нужд.

void write_to_stream(uv_stream_t* stream) {   
    uv_write_t* write_req = new uv_write_t;
    write_req.data = new char[1024];

    uv_buf_t buf{};
    buf.base = write_req.data;
    buf.len = 1024;

    // fill the buffer
    uv_write(write_req, stream, buf, 1, on_write);
}

void on_write(uv_write_t* req, int status) {

    delete[] req.data;
    delete req;
}

1 голос
/ 19 октября 2019

Поскольку libuv является библиотекой переменного тока, ее структуры должны быть стандартного типа. Таким образом, вы можете обернуть ваши uv_write_t и uv_buf_t в контекстную структуру, а затем привести обратно к контекстной структуре. См. Следующий пример:

struct write_context_t {
    uv_write_t write_req;
    uv_buf_t buf;
    ~write_context_t() {
        delete[] buf.base;
    }
}

void on_write(uv_write_t* req, int status) {
    write_context_t* context = reinterpret_cast<write_context_t*>(req);
    /* Do stuff ... */
    delete context;
}

void write_to_stream(uv_stream_t* stream) {   
    write_context_t* write_req = new write_context_t;

    /* fill your write_req and buf info here ... */

    // initiate write
    uv_write(&write_req.write_req, stream, write_req.buf, 1, on_write);
}

Это работает, потому что указатель на первый нестатический элемент данных стандартного объекта макета взаимно конвертируем с указателем на объект.

...