Facy random seed for qrand in kdelibs
Sebastian Trüg
trueg at kde.org
Tue Aug 3 10:57:22 BST 2010
Hi Thiago,
thanks a lot for your insight. I merely took this code from kdepim. But
your proposal seems much better. Do I understand correctly and Qt 4.6.4
does already seed properly?
In that case a backport to kde-qt would be great.
Cheers,
Sebastian
On 08/02/2010 05:23 PM, Thiago Macieira wrote:
> On Monday 2. August 2010 11.52.32 Sebastian Trüg wrote:
>> one of kdepim's Akonadi resources defines the method below to create a
>> proper random seed for qrand. IMHO we should put this in kdelibs
>> directly so all apps can benefit from it. Maybe KGlobal is the right
>> place for it?
>>
>> Any objections?
>
> Actually, after reading the code, yes, unfortunately, I do.
>
>> static void initRandomSeed()
>> {
>> static bool init = false;
>> if ( !init ) {
>> unsigned int seed;
>> init = true;
>> int fd = KDE_open( "/dev/urandom", O_RDONLY );
>> if ( fd < 0 || ::read( fd, &seed, sizeof( seed ) ) != sizeof( seed ) )
>> { // No /dev/urandom... try something else.
>> srand( getpid() );
>> seed = rand() + time( 0 );
>> }
>>
>> if ( fd >= 0 )
>> close( fd );
>>
>> qsrand( seed );
>> }
>> }
>
> This implementation isn't correct.
>
> You must set "init" as the last thing, otherwise other threads might skip over
> the initialisation and try to get the data before the seeding is complete.
>
> Using a "bool" isn't enough for this, since the compiler might reorder the
> instructions. You should use at least a volatile, but a QBasicAtomicInt is
> preferrable.
>
> But the big problem is that qsrand and qrand are thread-specific. You must run
> the above code once per started thread. Your code is global (once per
> application). So it won't work.
>
> The implementation in Qt 4.6.4 and 4.7.0 is preferred. If required, we can
> cherry-pick f28a27987fa4e1b2faa1c57188c128afb735f70a and
> 2ef8b92ececbf9d33d7c0b44f46c7c975fb0fdaa into the kde-qt 4.6.3-patched and
> master branches.
>
More information about the kde-core-devel
mailing list