tight: Hold fb and client refs while encoding

tight-scheduling-fix
Andri Yngvason 2020-09-27 17:17:22 +00:00
parent af38a643d9
commit e69006fc48
3 changed files with 16 additions and 7 deletions

View File

@ -51,7 +51,7 @@ struct tight_encoder {
struct rfb_pixel_format dfmt; struct rfb_pixel_format dfmt;
struct rfb_pixel_format sfmt; struct rfb_pixel_format sfmt;
const struct nvnc_fb* fb; struct nvnc_fb* fb;
uint32_t n_rects; uint32_t n_rects;
uint32_t n_jobs; uint32_t n_jobs;
@ -71,7 +71,7 @@ int tight_encoder_resize(struct tight_encoder* self, uint32_t width,
int tight_encode_frame(struct tight_encoder* self, int tight_encode_frame(struct tight_encoder* self,
const struct rfb_pixel_format* dfmt, const struct rfb_pixel_format* dfmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* sfmt, const struct rfb_pixel_format* sfmt,
struct pixman_region16* damage, struct pixman_region16* damage,
enum tight_quality quality, enum tight_quality quality,

View File

@ -541,14 +541,17 @@ static void process_fb_update_requests(struct nvnc_client* client)
case RFB_ENCODING_ZRLE: case RFB_ENCODING_ZRLE:
rc = schedule_client_update_fb(client, &damage); rc = schedule_client_update_fb(client, &damage);
break; break;
case RFB_ENCODING_TIGHT:; case RFB_ENCODING_TIGHT:
enum tight_quality quality = client_get_tight_quality(client); client_ref(client);
// TODO: Make sure we don't have use-after-free on client and fb enum tight_quality quality = client_get_tight_quality(client);
rc = tight_encode_frame(&client->tight_encoder, &client->pixfmt, rc = tight_encode_frame(&client->tight_encoder, &client->pixfmt,
fb, &server_fmt, &damage, quality, fb, &server_fmt, &damage, quality,
on_tight_encode_frame_done, client); on_tight_encode_frame_done, client);
if (rc < 0)
client_unref(client);
pixman_region_fini(&damage); pixman_region_fini(&damage);
break; break;
default: default:
@ -1186,6 +1189,7 @@ static void on_tight_encode_frame_done(struct vec* frame, void* userdata)
{ {
struct nvnc_client* client = userdata; struct nvnc_client* client = userdata;
finish_fb_update(client, frame); finish_fb_update(client, frame);
client_unref(client);
} }
static void on_client_update_fb_done(void* work) static void on_client_update_fb_done(void* work)

View File

@ -402,9 +402,11 @@ static void on_tight_zs_work_done(void* obj)
struct tight_zs_worker_ctx* ctx = aml_get_userdata(obj); struct tight_zs_worker_ctx* ctx = aml_get_userdata(obj);
struct tight_encoder* self = ctx->encoder; struct tight_encoder* self = ctx->encoder;
if (--self->n_jobs == 0) if (--self->n_jobs == 0) {
nvnc_fb_unref(self->fb);
schedule_tight_finish(self); schedule_tight_finish(self);
} }
}
static int tight_schedule_zs_work(struct tight_encoder* self, int index) static int tight_schedule_zs_work(struct tight_encoder* self, int index)
{ {
@ -479,7 +481,7 @@ static int schedule_tight_finish(struct tight_encoder* self)
int tight_encode_frame(struct tight_encoder* self, int tight_encode_frame(struct tight_encoder* self,
const struct rfb_pixel_format* dfmt, const struct rfb_pixel_format* dfmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* sfmt, const struct rfb_pixel_format* sfmt,
struct pixman_region16* damage, struct pixman_region16* damage,
enum tight_quality quality, enum tight_quality quality,
@ -503,7 +505,10 @@ int tight_encode_frame(struct tight_encoder* self,
encode_rect_count(&self->dst, self->n_rects); encode_rect_count(&self->dst, self->n_rects);
nvnc_fb_ref(self->fb);
if (tight_schedule_encoding_jobs(self) < 0) { if (tight_schedule_encoding_jobs(self) < 0) {
nvnc_fb_unref(self->fb);
vec_destroy(&self->dst); vec_destroy(&self->dst);
return -1; return -1;
} }