Re: cairo_xcb_surface_create() segfaults on second call with different xcb info
Ryan Flannery <[email protected]> Tue, 13 Nov 2018 20:26:58 -0500
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAMgLCAgELPzytcUqoco2zR+2buoNsWLoM-FT8f+-zwQJ9UGgTA@mail.gmail.com> |
On Sat, Nov 10, 2018 at 4:11 AM Uli Schlachter <[email protected]> wrote: > > On 10.11.18 06:36, Ryan Flannery wrote: > [...] > >> Also: Finishing the device automatically finishes all cairo_surface_t > >> instances for this XCB devices. > > > > Ok - this raises a question for me about the device state between > > surface creation. > > Do you mean one of the following: > > > > 1. Calling cairo_device_finish(cairo_surface_get_device(cs)) when > > destroying a xcb/cairo setup should, effectively, remove the state > > tracked in cairo_xcb_surface_create() (and thus allow a subsequent > > call with the same pointer value, but different contents, succeed)? > > > > -or- > > > > 2. That there's still state there and I should track that > > cairo_device_t* reference on my side, even if I call the > > cairo_device_finish() bits? > > I think I mean (1). Finishing the cairo_device_t instance tries to get > rid of everything that uses the underlying xcb_connection_t*. It does > not do this completely, but the difference should not matter to you. > > The reason is reference counting: Finishing the cairo_device_t finishes > everything using this cairo_device_t / xcb_connection_t. "Finishes" here > means "makes unusable". However, it does not actually free everything, > since other pieces of code could still have a reference that keeps the > cairo_device_t alive (e.g. through cairo_device_reference, > cairo_surface_reference, or just cairo_xcb_surface_create). All this > "state" is cannot be freed yet, because otherwise the code having that > reference would end up with a dangling pointer. But, any attempt of > using one of these objects generates a CAIRO_STATUS_SURFACE_FINISHED or > CAIRO_STATUS_DEVICE_FINISHED error status. > > The important bit for you is that finishing the connection removes the > cairo_device_t from cairo's internal cache, so any following attempts at > using the same xcb_connection_t will create a new cairo_device_t instance. > That worked! Calling cairo_device_finish(cairo_surface_get_device(cs)); before calling cairo_surface_destroy(cs) reliably solves the problem. And following the code you referenced I can see (1) why the segfault was happening in the first place and (2) how this resolves it. Many thanks again Uli! Cheers, -Ryan -- cairo mailing list [email protected] https://lists.cairographics.org/mailman/listinfo/cairo