Mir

Merge lp:~alan-griffiths/mir/improve-tidy-up-of-mir_connection_get_display_info into lp:mir

Proposed by Alan Griffiths
Status: Merged
Merged at revision: 1157
Proposed branch: lp:~alan-griffiths/mir/improve-tidy-up-of-mir_connection_get_display_info
Merge into: lp:mir
Diff against target: 109 lines (+51/-45)
1 file modified
src/client/mir_client_library.cpp (+51/-45)
To merge this branch: bzr merge lp:~alan-griffiths/mir/improve-tidy-up-of-mir_connection_get_display_info
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Daniel van Vugt Disapprove
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+190134@code.launchpad.net

Commit message

client: RAII version of ~alan-griffiths/mir/lock_guard-for-unique_lock

Description of the change

client: RAII version of ~alan-griffiths/mir/lock_guard-for-unique_lock

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I think this is a step backwards. The first hint is the increase in code size (+19/-9). But more importantly, this is difficult to read: unique_with_deleter. Much more difficult to read than the "mir_display_config_destroy(config)" you're aiming to replace. I would rather keep the code readable with mir_display_config_destroy.

RAII is not useful if it results in code that's less clear about the possibility of leaks than that which it replaces. And I think mir_connection_get_display_info is presently very clear on the lifetime of config.

Also, there are a few unrelated whitespace changes in src/client/mir_client_library.cpp.

review: Disapprove
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> I think this is a step backwards. The first hint is the increase in code size
> (+19/-9). But more importantly, this is difficult to read:
> unique_with_deleter. Much more difficult to read than the
> "mir_display_config_destroy(config)" you're aiming to replace. I would rather
> keep the code readable with mir_display_config_destroy.

You're missing that it fixes the leaks caused by "return" statements that bypass that call. Alternative fixes also add lines.

> RAII is not useful if it results in code that's less clear about the
> possibility of leaks than that which it replaces. And I think
> mir_connection_get_display_info is presently very clear on the lifetime of
> config.

A RAII version was requested by Thomas and Alf - an alternative fix (that I was happy) with has already landed.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

There are no return statements. The flow of mir_connection_get_display_info is very clear as it's not a long function.

I favour explicit deletion over implicit, if the latter is significantly more cryptic (as it is here).

But other people may disagree.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> There are no return statements. The flow of mir_connection_get_display_info is
> very clear as it's not a long function.

There were in the version you referred to in "the increase in code size (+19/-9)." The alternative fix I mentioned removed them (-c 1120 on development-branch).

Explicit deletion is problematic in the presence of exceptions (which shouldn't apply here) or return statements (which we've just discussed).

It is reasonable to prefer uniform use of RAII for cleanup.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> RAII is not useful if it results in code that's less clear about the possibility of leaks
> than that which it replaces.

In this case (and in general) RAII minimizes the possibility of leaks now and in the future.

A reasonable alternative approach not using RAII, like r1120 on development-branch, is both more cumbersome than this and is not future-proof. What if the function gradually gets more complicated? What if someone inadvertently adds a return? We didn't catch this last time, we may not catch it the next.

Plus, we are using RAII/smart pointers all over the place, I don't see a reason to make an exception here.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I don't think one can talk about "future proof" at the same time as making code less readable. If it's less readable, you're cursing future maintainers to either not comprehend the code (so can't maintain it and/or waste time), or to misunderstand it and introduce regressions. Leaks are not the only kind of bug, and having readable code is a better preventative measure. In fact, leaks are much less important and less severe than many of the conceivable outcomes of a future maintainer not understanding the code.

Revision history for this message
Kevin DuBois (kdub) wrote :

I think this is okay. Perhaps it would be more immediately readable if lines 51-53 were just a shared_ptr with a deleter though (less figuring out what the inlined function is doing). I do think raii is the right way to fix the problem, but can empathize with wanting to figure out less types of pointers.

Revision history for this message
kevin gunn (kgunn72) wrote :

granted i don't touch code everyday, but it does seem to me that RAII is an accepted paradigm that was created to avoid orphaning objects from an owning objects excpetion (...a good thing)
at the same time, Could some additional pointed comments be added to the code to solve the maintainability concern ?

note...i don't agree that we should look at code size generically as a measuring stick...i've certainly seen it go the other way where people trying to "shrink" code made it more enigmatic.

I would propose some comments to be added as to what the deleter is doing, how it helps in the exception instance...then call this good

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

My disapproval is only about style and readability. Please treat it like "Abstain" so we don't waste any more time arguing. I fully expect this to land still.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I'm hearing that some folks would prefer losing the helper function and:

    std::unique_ptr<MirDisplayConfiguration, decltype(&mir_display_config_destroy)> const config(

to:

    auto const config = unique_with_deleter(

I guess it is a trade off between syntactic noise and an unfamiliar helper function. Let me know.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/mir_client_library.cpp'
--- src/client/mir_client_library.cpp 2013-10-17 05:51:24 +0000
+++ src/client/mir_client_library.cpp 2013-10-17 10:51:13 +0000
@@ -289,54 +289,60 @@
289 mcl::delete_config_storage(configuration);289 mcl::delete_config_storage(configuration);
290}290}
291291
292namespace
293{
294template <typename Owned>
295inline std::unique_ptr<Owned, void(*)(Owned*)> unique_with_deleter(Owned* owned, void(*deleter)(Owned*))
296{
297 return {owned, deleter};
298}
299}
300
292//TODO: DEPRECATED: remove this function301//TODO: DEPRECATED: remove this function
293void mir_connection_get_display_info(MirConnection *connection, MirDisplayInfo *display_info)302void mir_connection_get_display_info(MirConnection *connection, MirDisplayInfo *display_info)
294{303{
295 auto config = mir_connection_create_display_config(connection);304 auto const config = unique_with_deleter(
296305 mir_connection_create_display_config(connection),
297 do306 &mir_display_config_destroy);
298 {307
299 if (config->num_outputs < 1)308 if (config->num_outputs < 1)
300 break;309 return;
301310
302 MirDisplayOutput* state = nullptr;311 MirDisplayOutput* state = nullptr;
303 // We can't handle more than one display, so just populate based on the first312 // We can't handle more than one display, so just populate based on the first
304 // active display we find.313 // active display we find.
305 for (unsigned int i = 0; i < config->num_outputs; ++i)314 for (unsigned int i = 0; i < config->num_outputs; ++i)
306 {315 {
307 if (config->outputs[i].used && config->outputs[i].connected &&316 if (config->outputs[i].used && config->outputs[i].connected &&
308 config->outputs[i].current_mode < config->outputs[i].num_modes)317 config->outputs[i].current_mode < config->outputs[i].num_modes)
309 {318 {
310 state = &config->outputs[i];319 state = &config->outputs[i];
311 break;320 break;
312 }321 }
313 }322 }
314 // Oh, oh! No connected outputs?!323 // Oh, oh! No connected outputs?!
315 if (state == nullptr)324 if (state == nullptr)
316 {325 {
317 memset(display_info, 0, sizeof(*display_info));326 memset(display_info, 0, sizeof(*display_info));
318 break;327 return;
319 }328 }
320329
321 MirDisplayMode mode = state->modes[state->current_mode];330 MirDisplayMode mode = state->modes[state->current_mode];
322331
323 display_info->width = mode.horizontal_resolution;332 display_info->width = mode.horizontal_resolution;
324 display_info->height = mode.vertical_resolution;333 display_info->height = mode.vertical_resolution;
325334
326 unsigned int format_items;335 unsigned int format_items;
327 if (state->num_output_formats > mir_supported_pixel_format_max)336 if (state->num_output_formats > mir_supported_pixel_format_max)
328 format_items = mir_supported_pixel_format_max;337 format_items = mir_supported_pixel_format_max;
329 else338 else
330 format_items = state->num_output_formats;339 format_items = state->num_output_formats;
331340
332 display_info->supported_pixel_format_items = format_items;341 display_info->supported_pixel_format_items = format_items;
333 for(auto i=0u; i < format_items; i++)342 for(auto i=0u; i < format_items; i++)
334 {343 {
335 display_info->supported_pixel_format[i] = state->output_formats[i];344 display_info->supported_pixel_format[i] = state->output_formats[i];
336 }345 }
337 } while (false);
338
339 mir_display_config_destroy(config);
340}346}
341347
342void mir_surface_get_graphics_region(MirSurface * surface, MirGraphicsRegion * graphics_region)348void mir_surface_get_graphics_region(MirSurface * surface, MirGraphicsRegion * graphics_region)

Subscribers

People subscribed via source and target branches