Mailinglist Archive: zypp-devel (92 mails)
| < Previous | Next > |
[zypp-devel] Be carefull when using class ProgressData!
- From: Michael Andres <ma@xxxxxxx>
- Date: Thu, 30 Aug 2007 14:47:03 +0200
- Message-id: <20070830124703.GA9310@xxxxxxx>
Unlike Report/Callback pairs (or not yet used Signal/Slots), ProgressData
reports are not guarded against a vanishing reciever.
A ProgressData object should have a limited lifetime. It should go
out of scope as the task is completed. Preferably it is a variable
local to some function. Not a class data member.
https://bugzilla.novell.com/show_bug.cgi?id=299680 shows what happens if
some ProgressData _ticks is a class data member:
Set up to report progress during RepoImpl creation, it is not
reset as the task has completed.
Far later, as the RepoImpl goes out of scope, the ProgressData
object sends it's final 'end of lifetime' report to a receiver
that no longer exists.
void task( ... )
{
ProgressData ticks; // limited lifetime!
}
If you need to trigger the same ProgressData object within multiple
functions, pass it per reference to the functions, ...
.. or at least take care ProgressData is reset at the end of the task:
#include "zypp/base/DtorReset.h"
class RepoImpl
{
public:
void task( ... )
{
DtorReset x( _ticks, ProgressData() );
DtorReset y( _taskRunning, false );
_taskRunning = true; //
_ticks = ProgressData( 10 ); // Expect range 0 -> 10
_tics.name( "test ticks" ); // Some arbitrary name
_tics.sendTo( _fnc ); // Send reports to _fnc
_ticks.toMin(); // start sending min (0)
longrun();
_ticks.toMax();
}
private:
void longrun()
{
while ( ! done ) {
...
if ( eror )
throw;
...
_ticks.tick();
}
}
ProgressData _ticks;
bool _taskRunning;
};
- task initializes _ticks to be a 'new' ProgressData.
- longrun is able to access _ticks
- DtorReset takes care _ticks is reset at the end of task, even if
an exception occurred.
DtorReset:
- DtorReset takes care _taskRunning is set to 'false' at the end of task,
to show that DtorReset is templated, thus not limited to certain types
(as long as they are copyable and assignable).
DtorReset assigns back some value:
DtorReset x( _flag, _flag ); // save and restore later
_flag = 0;
See also: class AutoDispose. Similar but calls some user defined
cleanup function:
{
AutoDispose<int> fd( 0 );
fd = open( "/tmp/foo" );
if ( fd == -1 )
return; // or error report
else
fd.setDispose( ::close );
// HERE: fd is guarded.
// The file will be closed when fd goes out of scope.
// More precise: when fd and all copies obtained from fd
// went out of scope.
..
// explicit close:
fd.resetDispose();
::close( fd );
fd = -1;
}
--
cu,
Michael Andres
+------------------------------------------------------------------+
Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4
+------------------------------------------------------------------+
Michael Andres YaST Development ma@xxxxxxxxxx
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg)
Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0
+------------------------------------------------------------------+
--
To unsubscribe, e-mail: zypp-devel+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: zypp-devel+help@xxxxxxxxxxxx
| < Previous | Next > |