[libcamera-devel] [PATCH v2 03/24] libcamera: controls: Avoid exception in ControlList count() and find()

Kieran Bingham kieran.bingham at ideasonboard.com
Wed Nov 20 10:17:05 CET 2019


Hi Laurent,

On 20/11/2019 03:48, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tue, Nov 19, 2019 at 03:46:12PM +0000, Kieran Bingham wrote:
>> On 08/11/2019 20:53, Laurent Pinchart wrote:
>>> The ControlList count() and find() methods use at() to lookup the
>>> control numerical ID in the idmap_. This causes an exception to be
>>> thrown if the ID doesn't exist in the map. Fix it by using the find()
>>> method instead.
>>>
>>> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>>> ---
>>>  src/libcamera/controls.cpp | 18 +++++++++++++++---
>>>  1 file changed, 15 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
>>> index 93ad2fc6a276..0c7cd449ad64 100644
>>> --- a/src/libcamera/controls.cpp
>>> +++ b/src/libcamera/controls.cpp
>>> @@ -491,7 +491,11 @@ const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const
>>>   */
>>>  ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
>>>  {
>>> -	return count(idmap_.at(id));
>>> +	auto iter = idmap_.find(id);
>>> +	if (iter == idmap_.end())
>>> +		return 0;
>>> +
>>> +	return count(iter->second);
>>
>> Is this further count() redundant?
>>
>> Has the desired item already been 'found' at that point, and thus we can
>> return '1'?
>>
>> I fear use of std::pair once again makes this hunk fairly horrible to
>> read as a standalone code segment. Even more so with the user of auto
>> iter. (yes, ->second is my ->first pet-peeve)
> 
> :-) I dislike it as well, but in this case it's nothing we can control.
> idmap_ is an std::unordered_map, and std::unordered_map::value_type is a
> std::pair. That's the C++ STL API. What we can do is use local variables
> to make this more explicit.

Yes, the use of local variables to make the naming explicit is what I
meant here ...

I feel like any use of ->first and ->second is the equivalent of naming
variables
  int integer = 0;

Just like the std::pair, here there is an integer, but it doesn't tell
me what it stores it for, The ->first ->second /are/ the first and
second parameter of the pair - but that doesn't tell me what they are
used for. And it leaves the reader blind (or worse, confused).

I feel strongly enough about this to say we should propose a coding
standard addition to say all use of std::pair should be named explicitly
by mapping to typed (and well named) local variables (which I expect the
compiler to optimise out), with perhaps an exception if the std::pair
return types are already exposed within the local function and "might"
be redundant.

What do you think ?

>> Actually - Looking below, I suspect the call to count is important,
>> because we might be counting something else.
> 
> Actually I don't think so. The idmap is generated with one entry per
> entry in ControlInfoMap, with a 1:1 mapping between the two, so I think
> we can just return 1 here. Or even better,
> 
> 	return idmap_.count(id);


That sounds even better.
Perhaps something like this then (Adjust as appropriate of course):

ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
{
 /*
  * The idmap is generated with one entry per entry in ControlInfoMap
  * with a 1:1 mapping between the two, therefore we count the relevant
  * idmap entries to establish the ControlInfoMap count without
  * performing an additional lookup.
  */

  return idmap_.count(id);
}

> 
>> Can we add a brief comment here or something to make all of this clear?
>>
>> Or expand the iter->second to a defined type so it's clear /what/ we're
>> counting.
>>
>>>  }
>>>  
>>>  /**
>>> @@ -502,7 +506,11 @@ ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
>>>   */
>>>  ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
>>>  {
>>> -	return find(idmap_.at(id));
>>> +	auto iter = idmap_.find(id);
>>> +	if (iter == idmap_.end())
>>> +		return end();
>>> +
>>> +	return find(iter->second);
>>>  }
>>>  
>>>  /**
>>> @@ -513,7 +521,11 @@ ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
>>>   */
>>>  ControlInfoMap::const_iterator ControlInfoMap::find(unsigned int id) const
>>>  {
>>> -	return find(idmap_.at(id));
>>> +	auto iter = idmap_.find(id);
>>> +	if (iter == idmap_.end())
>>> +		return end();
>>> +
>>> +	return find(iter->second);
>>>  }
>>>  
>>>  /**
> 

-- 
Regards
--
Kieran


More information about the libcamera-devel mailing list