[RFC,v1,1/1] treewide: Update to the C++20 standard
diff mbox series

Message ID 20251113110958.1117065-2-naush@raspberrypi.com
State New
Headers show
Series
  • Switch to C++20 standard
Related show

Commit Message

Naushir Patuck Nov. 13, 2025, 11:05 a.m. UTC
Switch to using the C++20 standard when compiling libcamera. This causes
a build error due to the deprecation of the following specialisation [1]

std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)

../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
  468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
      |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~

This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
specialisation instead. Unfortunately, this is not backward compatible
with C++17, so the fix must be included in this commit.

[1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 meson.build                | 2 +-
 src/libcamera/base/log.cpp | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

Comments

Kieran Bingham Nov. 13, 2025, 12:03 p.m. UTC | #1
Hi Naush,

Quoting Naushir Patuck (2025-11-13 11:05:31)
> Switch to using the C++20 standard when compiling libcamera. This causes
> a build error due to the deprecation of the following specialisation [1]
> 
> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
> 
> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
>   468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>       |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
> 
> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
> specialisation instead. Unfortunately, this is not backward compatible
> with C++17, so the fix must be included in this commit.

Thank you for this,

I think I'm in favour of updating here when we can.

We'll have to do a bit of a check to see if this impacts any projects
using libcamera but I think it's workable.

First part though will be CI:

 https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400

Quite a few breakages to tackle and that may be the hard part.

With a large matrix of compilers and differing support that might be the
tricky part. We'll have to identify if this will restict us to any
specific compiler version minimum.

--
Kieran


> 
> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> ---
>  meson.build                | 2 +-
>  src/libcamera/base/log.cpp | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index fd508fd7f6b5..74153e1e6ce9 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
>      default_options : [
>          'werror=true',
>          'warning_level=2',
> -        'cpp_std=c++17',
> +        'cpp_std=c++20',
>      ],
>      license : 'LGPL 2.1+')
>  
> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> index 81b550e21402..e65d83739315 100644
> --- a/src/libcamera/base/log.cpp
> +++ b/src/libcamera/base/log.cpp
> @@ -325,7 +325,7 @@ private:
>         std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
>         std::list<std::pair<std::string, LogSeverity>> levels_;
>  
> -       std::shared_ptr<LogOutput> output_;
> +       std::atomic<std::shared_ptr<LogOutput>> output_;
>  };
>  
>  bool Logger::destroyed_ = false;
> @@ -465,7 +465,7 @@ Logger *Logger::instance()
>   */
>  void Logger::write(const LogMessage &msg)
>  {
> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> +       std::shared_ptr<LogOutput> output = output_.load();
>         if (!output)
>                 return;
>  
> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
>   */
>  void Logger::backtrace()
>  {
> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> +       std::shared_ptr<LogOutput> output = output_.load();
>         if (!output)
>                 return;
>  
> -- 
> 2.51.0
>
Barnabás Pőcze Nov. 13, 2025, 12:24 p.m. UTC | #2
2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
> Hi Naush,
> 
> Quoting Naushir Patuck (2025-11-13 11:05:31)
>> Switch to using the C++20 standard when compiling libcamera. This causes
>> a build error due to the deprecation of the following specialisation [1]
>>
>> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
>>
>> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
>> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
>>    468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>        |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
>>
>> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
>> specialisation instead. Unfortunately, this is not backward compatible
>> with C++17, so the fix must be included in this commit.
> 
> Thank you for this,
> 
> I think I'm in favour of updating here when we can.
> 
> We'll have to do a bit of a check to see if this impacts any projects
> using libcamera but I think it's workable.
> 
> First part though will be CI:
> 
>   https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
> 
> Quite a few breakages to tackle and that may be the hard part.

I have been compiling libcamera as C++20 forever. Apart from the above
change, one needs to:

  (1) disable -Wvolatile because of g_once_init() in glib
  (2) disable -Wredundant-move in gcc 12 as well

---

As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
in some versions, so I ended up using

   #pragma GCC diagnostic ignored "-Wdeprecated-declarations"

---

Also, libpisp did not compile without warnings in C++20 the last time I checked.

---

There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267

---

C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364

/usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
   431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));


After some time I have given up on trying to fix this.

---

Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.

diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
index d4492d994b..3de6fc42a7 100644
--- a/src/gstreamer/gstlibcameraallocator.cpp
+++ b/src/gstreamer/gstlibcameraallocator.cpp
@@ -8,6 +8,7 @@
  
  #include "gstlibcameraallocator.h"
  
+#include <mutex>
  #include <utility>
  
  #include <libcamera/camera.h>
@@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
  GQuark FrameWrap::getQuark()
  {
         static gsize frame_quark = 0;
+       static std::once_flag frame_quark_once;
  
-       if (g_once_init_enter(&frame_quark)) {
-               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
-               g_once_init_leave(&frame_quark, quark);
-       }
+       std::call_once(frame_quark_once, [&] {
+               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
+       });
  
         return frame_quark;
  }


Regards,
Barnabás Pőcze

> 
> With a large matrix of compilers and differing support that might be the
> tricky part. We'll have to identify if this will restict us to any
> specific compiler version minimum.
> 
> --
> Kieran
> 
> 
>>
>> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
>> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
>> ---
>>   meson.build                | 2 +-
>>   src/libcamera/base/log.cpp | 6 +++---
>>   2 files changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/meson.build b/meson.build
>> index fd508fd7f6b5..74153e1e6ce9 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
>>       default_options : [
>>           'werror=true',
>>           'warning_level=2',
>> -        'cpp_std=c++17',
>> +        'cpp_std=c++20',
>>       ],
>>       license : 'LGPL 2.1+')
>>   
>> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
>> index 81b550e21402..e65d83739315 100644
>> --- a/src/libcamera/base/log.cpp
>> +++ b/src/libcamera/base/log.cpp
>> @@ -325,7 +325,7 @@ private:
>>          std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
>>          std::list<std::pair<std::string, LogSeverity>> levels_;
>>   
>> -       std::shared_ptr<LogOutput> output_;
>> +       std::atomic<std::shared_ptr<LogOutput>> output_;
>>   };
>>   
>>   bool Logger::destroyed_ = false;
>> @@ -465,7 +465,7 @@ Logger *Logger::instance()
>>    */
>>   void Logger::write(const LogMessage &msg)
>>   {
>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>> +       std::shared_ptr<LogOutput> output = output_.load();
>>          if (!output)
>>                  return;
>>   
>> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
>>    */
>>   void Logger::backtrace()
>>   {
>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>> +       std::shared_ptr<LogOutput> output = output_.load();
>>          if (!output)
>>                  return;
>>   
>> -- 
>> 2.51.0
>>
Laurent Pinchart Nov. 13, 2025, 12:49 p.m. UTC | #3
On Thu, Nov 13, 2025 at 01:24:18PM +0100, Barnabás Pőcze wrote:
> 2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
> > Quoting Naushir Patuck (2025-11-13 11:05:31)
> >> Switch to using the C++20 standard when compiling libcamera. This causes
> >> a build error due to the deprecation of the following specialisation [1]
> >>
> >> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
> >>
> >> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
> >> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
> >>    468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>        |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
> >>
> >> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
> >> specialisation instead. Unfortunately, this is not backward compatible
> >> with C++17, so the fix must be included in this commit.
> > 
> > Thank you for this,
> > 
> > I think I'm in favour of updating here when we can.
> > 
> > We'll have to do a bit of a check to see if this impacts any projects
> > using libcamera but I think it's workable.
> > 
> > First part though will be CI:
> > 
> >   https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
> > 
> > Quite a few breakages to tackle and that may be the hard part.
> 
> I have been compiling libcamera as C++20 forever. Apart from the above
> change, one needs to:
> 
>   (1) disable -Wvolatile because of g_once_init() in glib
>   (2) disable -Wredundant-move in gcc 12 as well
> 
> ---
> 
> As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
> in some versions, so I ended up using
> 
>    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> 
> ---
> 
> Also, libpisp did not compile without warnings in C++20 the last time I checked.
> 
> ---
> 
> There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267
> 
> ---
> 
> C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364
> 
> /usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
>    431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
> 
> 
> After some time I have given up on trying to fix this.
> 
> ---
> 
> Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.
> 
> diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
> index d4492d994b..3de6fc42a7 100644
> --- a/src/gstreamer/gstlibcameraallocator.cpp
> +++ b/src/gstreamer/gstlibcameraallocator.cpp
> @@ -8,6 +8,7 @@
>   
>   #include "gstlibcameraallocator.h"
>   
> +#include <mutex>
>   #include <utility>
>   
>   #include <libcamera/camera.h>
> @@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
>   GQuark FrameWrap::getQuark()
>   {
>          static gsize frame_quark = 0;
> +       static std::once_flag frame_quark_once;
>   
> -       if (g_once_init_enter(&frame_quark)) {
> -               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
> -               g_once_init_leave(&frame_quark, quark);
> -       }
> +       std::call_once(frame_quark_once, [&] {
> +               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> +       });
>   
>          return frame_quark;
>   }

How about

GQuark FrameWrap::getQuark()
{
	static gsize frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
	return frame_quark;
}

According to
https://en.cppreference.com/w/cpp/language/storage_duration.html#Static_block_variables,

  If multiple threads attempt to initialize the same static local
  variable concurrently, the initialization occurs exactly once (similar
  behavior can be obtained for arbitrary functions with std::call_once).

> > With a large matrix of compilers and differing support that might be the
> > tricky part. We'll have to identify if this will restict us to any
> > specific compiler version minimum.
> > 
> >> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
> >> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> >> ---
> >>   meson.build                | 2 +-
> >>   src/libcamera/base/log.cpp | 6 +++---
> >>   2 files changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/meson.build b/meson.build
> >> index fd508fd7f6b5..74153e1e6ce9 100644
> >> --- a/meson.build
> >> +++ b/meson.build
> >> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
> >>       default_options : [
> >>           'werror=true',
> >>           'warning_level=2',
> >> -        'cpp_std=c++17',
> >> +        'cpp_std=c++20',
> >>       ],
> >>       license : 'LGPL 2.1+')
> >>   
> >> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> >> index 81b550e21402..e65d83739315 100644
> >> --- a/src/libcamera/base/log.cpp
> >> +++ b/src/libcamera/base/log.cpp
> >> @@ -325,7 +325,7 @@ private:
> >>          std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
> >>          std::list<std::pair<std::string, LogSeverity>> levels_;
> >>   
> >> -       std::shared_ptr<LogOutput> output_;
> >> +       std::atomic<std::shared_ptr<LogOutput>> output_;
> >>   };
> >>   
> >>   bool Logger::destroyed_ = false;
> >> @@ -465,7 +465,7 @@ Logger *Logger::instance()
> >>    */
> >>   void Logger::write(const LogMessage &msg)
> >>   {
> >> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >> +       std::shared_ptr<LogOutput> output = output_.load();
> >>          if (!output)
> >>                  return;
> >>   
> >> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
> >>    */
> >>   void Logger::backtrace()
> >>   {
> >> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >> +       std::shared_ptr<LogOutput> output = output_.load();
> >>          if (!output)
> >>                  return;
> >>
Barnabás Pőcze Nov. 13, 2025, 12:54 p.m. UTC | #4
2025. 11. 13. 13:49 keltezéssel, Laurent Pinchart írta:
> On Thu, Nov 13, 2025 at 01:24:18PM +0100, Barnabás Pőcze wrote:
>> 2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
>>> Quoting Naushir Patuck (2025-11-13 11:05:31)
>>>> Switch to using the C++20 standard when compiling libcamera. This causes
>>>> a build error due to the deprecation of the following specialisation [1]
>>>>
>>>> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
>>>>
>>>> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
>>>> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
>>>>     468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>>         |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
>>>>
>>>> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
>>>> specialisation instead. Unfortunately, this is not backward compatible
>>>> with C++17, so the fix must be included in this commit.
>>>
>>> Thank you for this,
>>>
>>> I think I'm in favour of updating here when we can.
>>>
>>> We'll have to do a bit of a check to see if this impacts any projects
>>> using libcamera but I think it's workable.
>>>
>>> First part though will be CI:
>>>
>>>    https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
>>>
>>> Quite a few breakages to tackle and that may be the hard part.
>>
>> I have been compiling libcamera as C++20 forever. Apart from the above
>> change, one needs to:
>>
>>    (1) disable -Wvolatile because of g_once_init() in glib
>>    (2) disable -Wredundant-move in gcc 12 as well
>>
>> ---
>>
>> As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
>> in some versions, so I ended up using
>>
>>     #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
>>
>> ---
>>
>> Also, libpisp did not compile without warnings in C++20 the last time I checked.
>>
>> ---
>>
>> There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267
>>
>> ---
>>
>> C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364
>>
>> /usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
>>     431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
>>
>>
>> After some time I have given up on trying to fix this.
>>
>> ---
>>
>> Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.
>>
>> diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
>> index d4492d994b..3de6fc42a7 100644
>> --- a/src/gstreamer/gstlibcameraallocator.cpp
>> +++ b/src/gstreamer/gstlibcameraallocator.cpp
>> @@ -8,6 +8,7 @@
>>    
>>    #include "gstlibcameraallocator.h"
>>    
>> +#include <mutex>
>>    #include <utility>
>>    
>>    #include <libcamera/camera.h>
>> @@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
>>    GQuark FrameWrap::getQuark()
>>    {
>>           static gsize frame_quark = 0;
>> +       static std::once_flag frame_quark_once;
>>    
>> -       if (g_once_init_enter(&frame_quark)) {
>> -               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
>> -               g_once_init_leave(&frame_quark, quark);
>> -       }
>> +       std::call_once(frame_quark_once, [&] {
>> +               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
>> +       });
>>    
>>           return frame_quark;
>>    }
> 
> How about
> 
> GQuark FrameWrap::getQuark()
> {
> 	static gsize frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> 	return frame_quark;
> }

Ahh, yes, that should work, and is much better.


> 
> According to
> https://en.cppreference.com/w/cpp/language/storage_duration.html#Static_block_variables,
> 
>    If multiple threads attempt to initialize the same static local
>    variable concurrently, the initialization occurs exactly once (similar
>    behavior can be obtained for arbitrary functions with std::call_once).
> 
>>> With a large matrix of compilers and differing support that might be the
>>> tricky part. We'll have to identify if this will restict us to any
>>> specific compiler version minimum.
>>>
>>>> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
>>>> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
>>>> ---
>>>>    meson.build                | 2 +-
>>>>    src/libcamera/base/log.cpp | 6 +++---
>>>>    2 files changed, 4 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/meson.build b/meson.build
>>>> index fd508fd7f6b5..74153e1e6ce9 100644
>>>> --- a/meson.build
>>>> +++ b/meson.build
>>>> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
>>>>        default_options : [
>>>>            'werror=true',
>>>>            'warning_level=2',
>>>> -        'cpp_std=c++17',
>>>> +        'cpp_std=c++20',
>>>>        ],
>>>>        license : 'LGPL 2.1+')
>>>>    
>>>> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
>>>> index 81b550e21402..e65d83739315 100644
>>>> --- a/src/libcamera/base/log.cpp
>>>> +++ b/src/libcamera/base/log.cpp
>>>> @@ -325,7 +325,7 @@ private:
>>>>           std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
>>>>           std::list<std::pair<std::string, LogSeverity>> levels_;
>>>>    
>>>> -       std::shared_ptr<LogOutput> output_;
>>>> +       std::atomic<std::shared_ptr<LogOutput>> output_;
>>>>    };
>>>>    
>>>>    bool Logger::destroyed_ = false;
>>>> @@ -465,7 +465,7 @@ Logger *Logger::instance()
>>>>     */
>>>>    void Logger::write(const LogMessage &msg)
>>>>    {
>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>> +       std::shared_ptr<LogOutput> output = output_.load();
>>>>           if (!output)
>>>>                   return;
>>>>    
>>>> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
>>>>     */
>>>>    void Logger::backtrace()
>>>>    {
>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>> +       std::shared_ptr<LogOutput> output = output_.load();
>>>>           if (!output)
>>>>                   return;
>>>>    
>
Naushir Patuck Nov. 13, 2025, 1:40 p.m. UTC | #5
Hi all,

I should have mentioned that I was expecting many more compile errors
to crop up with the CI compiler matrix :)  I'll attempt at bashing
through them to see what's involved with making this change.  But good
to see there's an appetite to get C++20 support merged!

Regards,
Naush



On Thu, 13 Nov 2025 at 12:54, Barnabás Pőcze
<barnabas.pocze@ideasonboard.com> wrote:
>
> 2025. 11. 13. 13:49 keltezéssel, Laurent Pinchart írta:
> > On Thu, Nov 13, 2025 at 01:24:18PM +0100, Barnabás Pőcze wrote:
> >> 2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
> >>> Quoting Naushir Patuck (2025-11-13 11:05:31)
> >>>> Switch to using the C++20 standard when compiling libcamera. This causes
> >>>> a build error due to the deprecation of the following specialisation [1]
> >>>>
> >>>> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
> >>>>
> >>>> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
> >>>> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
> >>>>     468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>>         |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
> >>>>
> >>>> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
> >>>> specialisation instead. Unfortunately, this is not backward compatible
> >>>> with C++17, so the fix must be included in this commit.
> >>>
> >>> Thank you for this,
> >>>
> >>> I think I'm in favour of updating here when we can.
> >>>
> >>> We'll have to do a bit of a check to see if this impacts any projects
> >>> using libcamera but I think it's workable.
> >>>
> >>> First part though will be CI:
> >>>
> >>>    https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
> >>>
> >>> Quite a few breakages to tackle and that may be the hard part.
> >>
> >> I have been compiling libcamera as C++20 forever. Apart from the above
> >> change, one needs to:
> >>
> >>    (1) disable -Wvolatile because of g_once_init() in glib
> >>    (2) disable -Wredundant-move in gcc 12 as well
> >>
> >> ---
> >>
> >> As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
> >> in some versions, so I ended up using
> >>
> >>     #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> >>
> >> ---
> >>
> >> Also, libpisp did not compile without warnings in C++20 the last time I checked.
> >>
> >> ---
> >>
> >> There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267
> >>
> >> ---
> >>
> >> C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364
> >>
> >> /usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
> >>     431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
> >>
> >>
> >> After some time I have given up on trying to fix this.
> >>
> >> ---
> >>
> >> Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.
> >>
> >> diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
> >> index d4492d994b..3de6fc42a7 100644
> >> --- a/src/gstreamer/gstlibcameraallocator.cpp
> >> +++ b/src/gstreamer/gstlibcameraallocator.cpp
> >> @@ -8,6 +8,7 @@
> >>
> >>    #include "gstlibcameraallocator.h"
> >>
> >> +#include <mutex>
> >>    #include <utility>
> >>
> >>    #include <libcamera/camera.h>
> >> @@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
> >>    GQuark FrameWrap::getQuark()
> >>    {
> >>           static gsize frame_quark = 0;
> >> +       static std::once_flag frame_quark_once;
> >>
> >> -       if (g_once_init_enter(&frame_quark)) {
> >> -               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
> >> -               g_once_init_leave(&frame_quark, quark);
> >> -       }
> >> +       std::call_once(frame_quark_once, [&] {
> >> +               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> >> +       });
> >>
> >>           return frame_quark;
> >>    }
> >
> > How about
> >
> > GQuark FrameWrap::getQuark()
> > {
> >       static gsize frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> >       return frame_quark;
> > }
>
> Ahh, yes, that should work, and is much better.
>
>
> >
> > According to
> > https://en.cppreference.com/w/cpp/language/storage_duration.html#Static_block_variables,
> >
> >    If multiple threads attempt to initialize the same static local
> >    variable concurrently, the initialization occurs exactly once (similar
> >    behavior can be obtained for arbitrary functions with std::call_once).
> >
> >>> With a large matrix of compilers and differing support that might be the
> >>> tricky part. We'll have to identify if this will restict us to any
> >>> specific compiler version minimum.
> >>>
> >>>> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
> >>>> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> >>>> ---
> >>>>    meson.build                | 2 +-
> >>>>    src/libcamera/base/log.cpp | 6 +++---
> >>>>    2 files changed, 4 insertions(+), 4 deletions(-)
> >>>>
> >>>> diff --git a/meson.build b/meson.build
> >>>> index fd508fd7f6b5..74153e1e6ce9 100644
> >>>> --- a/meson.build
> >>>> +++ b/meson.build
> >>>> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
> >>>>        default_options : [
> >>>>            'werror=true',
> >>>>            'warning_level=2',
> >>>> -        'cpp_std=c++17',
> >>>> +        'cpp_std=c++20',
> >>>>        ],
> >>>>        license : 'LGPL 2.1+')
> >>>>
> >>>> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> >>>> index 81b550e21402..e65d83739315 100644
> >>>> --- a/src/libcamera/base/log.cpp
> >>>> +++ b/src/libcamera/base/log.cpp
> >>>> @@ -325,7 +325,7 @@ private:
> >>>>           std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
> >>>>           std::list<std::pair<std::string, LogSeverity>> levels_;
> >>>>
> >>>> -       std::shared_ptr<LogOutput> output_;
> >>>> +       std::atomic<std::shared_ptr<LogOutput>> output_;
> >>>>    };
> >>>>
> >>>>    bool Logger::destroyed_ = false;
> >>>> @@ -465,7 +465,7 @@ Logger *Logger::instance()
> >>>>     */
> >>>>    void Logger::write(const LogMessage &msg)
> >>>>    {
> >>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>> +       std::shared_ptr<LogOutput> output = output_.load();
> >>>>           if (!output)
> >>>>                   return;
> >>>>
> >>>> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
> >>>>     */
> >>>>    void Logger::backtrace()
> >>>>    {
> >>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>> +       std::shared_ptr<LogOutput> output = output_.load();
> >>>>           if (!output)
> >>>>                   return;
> >>>>
> >
>
Barnabás Pőcze Nov. 13, 2025, 1:41 p.m. UTC | #6
2025. 11. 13. 13:54 keltezéssel, Barnabás Pőcze írta:
> 2025. 11. 13. 13:49 keltezéssel, Laurent Pinchart írta:
>> On Thu, Nov 13, 2025 at 01:24:18PM +0100, Barnabás Pőcze wrote:
>>> 2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
>>>> Quoting Naushir Patuck (2025-11-13 11:05:31)
>>>>> Switch to using the C++20 standard when compiling libcamera. This causes
>>>>> a build error due to the deprecation of the following specialisation [1]
>>>>>
>>>>> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
>>>>>
>>>>> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
>>>>> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
>>>>>     468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>>>         |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
>>>>>
>>>>> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
>>>>> specialisation instead. Unfortunately, this is not backward compatible
>>>>> with C++17, so the fix must be included in this commit.
>>>>
>>>> Thank you for this,
>>>>
>>>> I think I'm in favour of updating here when we can.
>>>>
>>>> We'll have to do a bit of a check to see if this impacts any projects
>>>> using libcamera but I think it's workable.
>>>>
>>>> First part though will be CI:
>>>>
>>>>    https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
>>>>
>>>> Quite a few breakages to tackle and that may be the hard part.
>>>
>>> I have been compiling libcamera as C++20 forever. Apart from the above
>>> change, one needs to:
>>>
>>>    (1) disable -Wvolatile because of g_once_init() in glib
>>>    (2) disable -Wredundant-move in gcc 12 as well
>>>
>>> ---
>>>
>>> As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
>>> in some versions, so I ended up using
>>>
>>>     #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
>>>
>>> ---
>>>
>>> Also, libpisp did not compile without warnings in C++20 the last time I checked.
>>>
>>> ---
>>>
>>> There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267
>>>
>>> ---
>>>
>>> C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364
>>>
>>> /usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
>>>     431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
>>>
>>>
>>> After some time I have given up on trying to fix this.
>>>
>>> ---
>>>
>>> Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.
>>>
>>> diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
>>> index d4492d994b..3de6fc42a7 100644
>>> --- a/src/gstreamer/gstlibcameraallocator.cpp
>>> +++ b/src/gstreamer/gstlibcameraallocator.cpp
>>> @@ -8,6 +8,7 @@
>>>    #include "gstlibcameraallocator.h"
>>> +#include <mutex>
>>>    #include <utility>
>>>    #include <libcamera/camera.h>
>>> @@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
>>>    GQuark FrameWrap::getQuark()
>>>    {
>>>           static gsize frame_quark = 0;
>>> +       static std::once_flag frame_quark_once;
>>> -       if (g_once_init_enter(&frame_quark)) {
>>> -               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
>>> -               g_once_init_leave(&frame_quark, quark);
>>> -       }
>>> +       std::call_once(frame_quark_once, [&] {
>>> +               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
>>> +       });
>>>           return frame_quark;
>>>    }
>>
>> How about
>>
>> GQuark FrameWrap::getQuark()
>> {
>>     static gsize frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
>>     return frame_quark;
>> }
> 
> Ahh, yes, that should work, and is much better.

Unfortunately I misremembered and this is not enough. `-Wno-volatile` is needed
because `G_DEFINE_TYPE_*()` macros contain `g_once_init()`.

Regardless, it might still be worth it to simplify the code.

> 
> 
>>
>> According to
>> https://en.cppreference.com/w/cpp/language/storage_duration.html#Static_block_variables,
>>
>>    If multiple threads attempt to initialize the same static local
>>    variable concurrently, the initialization occurs exactly once (similar
>>    behavior can be obtained for arbitrary functions with std::call_once).
>>
>>>> With a large matrix of compilers and differing support that might be the
>>>> tricky part. We'll have to identify if this will restict us to any
>>>> specific compiler version minimum.
>>>>
>>>>> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
>>>>> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
>>>>> ---
>>>>>    meson.build                | 2 +-
>>>>>    src/libcamera/base/log.cpp | 6 +++---
>>>>>    2 files changed, 4 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/meson.build b/meson.build
>>>>> index fd508fd7f6b5..74153e1e6ce9 100644
>>>>> --- a/meson.build
>>>>> +++ b/meson.build
>>>>> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
>>>>>        default_options : [
>>>>>            'werror=true',
>>>>>            'warning_level=2',
>>>>> -        'cpp_std=c++17',
>>>>> +        'cpp_std=c++20',
>>>>>        ],
>>>>>        license : 'LGPL 2.1+')
>>>>> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
>>>>> index 81b550e21402..e65d83739315 100644
>>>>> --- a/src/libcamera/base/log.cpp
>>>>> +++ b/src/libcamera/base/log.cpp
>>>>> @@ -325,7 +325,7 @@ private:
>>>>>           std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
>>>>>           std::list<std::pair<std::string, LogSeverity>> levels_;
>>>>> -       std::shared_ptr<LogOutput> output_;
>>>>> +       std::atomic<std::shared_ptr<LogOutput>> output_;
>>>>>    };
>>>>>    bool Logger::destroyed_ = false;
>>>>> @@ -465,7 +465,7 @@ Logger *Logger::instance()
>>>>>     */
>>>>>    void Logger::write(const LogMessage &msg)
>>>>>    {
>>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>>> +       std::shared_ptr<LogOutput> output = output_.load();
>>>>>           if (!output)
>>>>>                   return;
>>>>> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
>>>>>     */
>>>>>    void Logger::backtrace()
>>>>>    {
>>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
>>>>> +       std::shared_ptr<LogOutput> output = output_.load();
>>>>>           if (!output)
>>>>>                   return;
>>
>
Laurent Pinchart Nov. 13, 2025, 3:32 p.m. UTC | #7
On Thu, Nov 13, 2025 at 02:41:52PM +0100, Barnabás Pőcze wrote:
> 2025. 11. 13. 13:54 keltezéssel, Barnabás Pőcze írta:
> > 2025. 11. 13. 13:49 keltezéssel, Laurent Pinchart írta:
> >> On Thu, Nov 13, 2025 at 01:24:18PM +0100, Barnabás Pőcze wrote:
> >>> 2025. 11. 13. 13:03 keltezéssel, Kieran Bingham írta:
> >>>> Quoting Naushir Patuck (2025-11-13 11:05:31)
> >>>>> Switch to using the C++20 standard when compiling libcamera. This causes
> >>>>> a build error due to the deprecation of the following specialisation [1]
> >>>>>
> >>>>> std::shared_ptr<T> atomic_load(const std::shared_ptr<T>* p)
> >>>>>
> >>>>> ../src/libcamera/base/log.cpp: In member function 'void libcamera::Logger::write(const libcamera::LogMessage&)':
> >>>>> ../src/libcamera/base/log.cpp:468:61: error: 'std::shared_ptr<_Tp> std::atomic_load(const shared_ptr<_Tp>*) [with _Tp = libcamera::LogOutput]' is deprecated: use 'std::atomic<std::shared_ptr<T>>' instead [-Werror=deprecated-declarations]
> >>>>>     468 |         std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>>>         |                                             ~~~~~~~~~~~~~~~~^~~~~~~~~~
> >>>>>
> >>>>> This error is fixed by switching to the std::atomic<std::shared_ptr<T>>
> >>>>> specialisation instead. Unfortunately, this is not backward compatible
> >>>>> with C++17, so the fix must be included in this commit.
> >>>>
> >>>> Thank you for this,
> >>>>
> >>>> I think I'm in favour of updating here when we can.
> >>>>
> >>>> We'll have to do a bit of a check to see if this impacts any projects
> >>>> using libcamera but I think it's workable.
> >>>>
> >>>> First part though will be CI:
> >>>>
> >>>>    https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1546400
> >>>>
> >>>> Quite a few breakages to tackle and that may be the hard part.
> >>>
> >>> I have been compiling libcamera as C++20 forever. Apart from the above
> >>> change, one needs to:
> >>>
> >>>    (1) disable -Wvolatile because of g_once_init() in glib
> >>>    (2) disable -Wredundant-move in gcc 12 as well
> >>>
> >>> ---
> >>>
> >>> As far as I remember `std::atomic<std::shared_ptr<>>` is not supported
> >>> in some versions, so I ended up using
> >>>
> >>>     #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> >>>
> >>> ---
> >>>
> >>> Also, libpisp did not compile without warnings in C++20 the last time I checked.
> >>>
> >>> ---
> >>>
> >>> There is also this peculiar issue: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267
> >>>
> >>> ---
> >>>
> >>> C++20 also triggers this error: https://gitlab.freedesktop.org/camera/libcamera/-/jobs/87812672#L364
> >>>
> >>> /usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
> >>>     431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
> >>>
> >>>
> >>> After some time I have given up on trying to fix this.
> >>>
> >>> ---
> >>>
> >>> Actually, to address (1), it should be sufficient to use `std::call_once()`, e.g.
> >>>
> >>> diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp
> >>> index d4492d994b..3de6fc42a7 100644
> >>> --- a/src/gstreamer/gstlibcameraallocator.cpp
> >>> +++ b/src/gstreamer/gstlibcameraallocator.cpp
> >>> @@ -8,6 +8,7 @@
> >>>    #include "gstlibcameraallocator.h"
> >>> +#include <mutex>
> >>>    #include <utility>
> >>>    #include <libcamera/camera.h>
> >>> @@ -77,11 +78,11 @@ FrameWrap::~FrameWrap()
> >>>    GQuark FrameWrap::getQuark()
> >>>    {
> >>>           static gsize frame_quark = 0;
> >>> +       static std::once_flag frame_quark_once;
> >>> -       if (g_once_init_enter(&frame_quark)) {
> >>> -               GQuark quark = g_quark_from_string("GstLibcameraFrameWrap");
> >>> -               g_once_init_leave(&frame_quark, quark);
> >>> -       }
> >>> +       std::call_once(frame_quark_once, [&] {
> >>> +               frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> >>> +       });
> >>>           return frame_quark;
> >>>    }
> >>
> >> How about
> >>
> >> GQuark FrameWrap::getQuark()
> >> {
> >>     static gsize frame_quark = g_quark_from_string("GstLibcameraFrameWrap");
> >>     return frame_quark;
> >> }
> > 
> > Ahh, yes, that should work, and is much better.
> 
> Unfortunately I misremembered and this is not enough. `-Wno-volatile` is needed
> because `G_DEFINE_TYPE_*()` macros contain `g_once_init()`.

Please make this conditional to the glib version.

> Regardless, it might still be worth it to simplify the code.
> 
> >> According to
> >> https://en.cppreference.com/w/cpp/language/storage_duration.html#Static_block_variables,
> >>
> >>    If multiple threads attempt to initialize the same static local
> >>    variable concurrently, the initialization occurs exactly once (similar
> >>    behavior can be obtained for arbitrary functions with std::call_once).
> >>
> >>>> With a large matrix of compilers and differing support that might be the
> >>>> tricky part. We'll have to identify if this will restict us to any
> >>>> specific compiler version minimum.
> >>>>
> >>>>> [1]: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic.html
> >>>>> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
> >>>>> ---
> >>>>>    meson.build                | 2 +-
> >>>>>    src/libcamera/base/log.cpp | 6 +++---
> >>>>>    2 files changed, 4 insertions(+), 4 deletions(-)
> >>>>>
> >>>>> diff --git a/meson.build b/meson.build
> >>>>> index fd508fd7f6b5..74153e1e6ce9 100644
> >>>>> --- a/meson.build
> >>>>> +++ b/meson.build
> >>>>> @@ -6,7 +6,7 @@ project('libcamera', 'c', 'cpp',
> >>>>>        default_options : [
> >>>>>            'werror=true',
> >>>>>            'warning_level=2',
> >>>>> -        'cpp_std=c++17',
> >>>>> +        'cpp_std=c++20',
> >>>>>        ],
> >>>>>        license : 'LGPL 2.1+')
> >>>>> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> >>>>> index 81b550e21402..e65d83739315 100644
> >>>>> --- a/src/libcamera/base/log.cpp
> >>>>> +++ b/src/libcamera/base/log.cpp
> >>>>> @@ -325,7 +325,7 @@ private:
> >>>>>           std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
> >>>>>           std::list<std::pair<std::string, LogSeverity>> levels_;
> >>>>> -       std::shared_ptr<LogOutput> output_;
> >>>>> +       std::atomic<std::shared_ptr<LogOutput>> output_;
> >>>>>    };
> >>>>>    bool Logger::destroyed_ = false;
> >>>>> @@ -465,7 +465,7 @@ Logger *Logger::instance()
> >>>>>     */
> >>>>>    void Logger::write(const LogMessage &msg)
> >>>>>    {
> >>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>>> +       std::shared_ptr<LogOutput> output = output_.load();
> >>>>>           if (!output)
> >>>>>                   return;
> >>>>> @@ -477,7 +477,7 @@ void Logger::write(const LogMessage &msg)
> >>>>>     */
> >>>>>    void Logger::backtrace()
> >>>>>    {
> >>>>> -       std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
> >>>>> +       std::shared_ptr<LogOutput> output = output_.load();
> >>>>>           if (!output)
> >>>>>                   return;

Patch
diff mbox series

diff --git a/meson.build b/meson.build
index fd508fd7f6b5..74153e1e6ce9 100644
--- a/meson.build
+++ b/meson.build
@@ -6,7 +6,7 @@  project('libcamera', 'c', 'cpp',
     default_options : [
         'werror=true',
         'warning_level=2',
-        'cpp_std=c++17',
+        'cpp_std=c++20',
     ],
     license : 'LGPL 2.1+')
 
diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
index 81b550e21402..e65d83739315 100644
--- a/src/libcamera/base/log.cpp
+++ b/src/libcamera/base/log.cpp
@@ -325,7 +325,7 @@  private:
 	std::vector<std::unique_ptr<LogCategory>> categories_ LIBCAMERA_TSA_GUARDED_BY(mutex_);
 	std::list<std::pair<std::string, LogSeverity>> levels_;
 
-	std::shared_ptr<LogOutput> output_;
+	std::atomic<std::shared_ptr<LogOutput>> output_;
 };
 
 bool Logger::destroyed_ = false;
@@ -465,7 +465,7 @@  Logger *Logger::instance()
  */
 void Logger::write(const LogMessage &msg)
 {
-	std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
+	std::shared_ptr<LogOutput> output = output_.load();
 	if (!output)
 		return;
 
@@ -477,7 +477,7 @@  void Logger::write(const LogMessage &msg)
  */
 void Logger::backtrace()
 {
-	std::shared_ptr<LogOutput> output = std::atomic_load(&output_);
+	std::shared_ptr<LogOutput> output = output_.load();
 	if (!output)
 		return;