It appears that because the data is created lazily on first access, the pointer or the reference to your singleton is read-write. This means that you do need a critical section.
In fact, the desire to avoid a critical section while keeping the lazy initialization in this situation has been so universally strong that it lead to the creation of the double-checked locking antipattern.
On the other hand, if you were to initialize your singleton eagerly before the reads, you would be able to avoid a critical section for accessing an immutable object through a constant pointer / reference.