more work on refs
This commit is contained in:
parent
588243c665
commit
4fccf06e5d
23
TODO
23
TODO
|
@ -1,3 +1,26 @@
|
||||||
|
- call:
|
||||||
|
|
||||||
|
vips_object_unref_outputs( object );
|
||||||
|
|
||||||
|
in more places .. a good test is
|
||||||
|
|
||||||
|
vips copy wtc.jpg x.v
|
||||||
|
|
||||||
|
where wtc.jpg is an empty file
|
||||||
|
|
||||||
|
we need to catch all the error paths out of VipsForeign
|
||||||
|
|
||||||
|
would catching in vips_call_split() be enough?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- we also have vips_argument_dispose_all() and call it from vips_call()
|
||||||
|
vips_call_split(), does this do the same job?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- test vips_foreign_load_vips_get_flags(), sense inverted?
|
- test vips_foreign_load_vips_get_flags(), sense inverted?
|
||||||
|
|
||||||
we have various printf()s left in the byteswap codepath
|
we have various printf()s left in the byteswap codepath
|
||||||
|
|
|
@ -311,11 +311,12 @@ vips_arithmetic_build( VipsObject *object )
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
g_object_set( arithmetic, "out", vips_image_new(), NULL );
|
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->
|
||||||
|
build( object ) )
|
||||||
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) )
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
g_object_set( arithmetic, "out", vips_image_new(), NULL );
|
||||||
|
|
||||||
/* No need to check input bands, bandalike will do this for us.
|
/* No need to check input bands, bandalike will do this for us.
|
||||||
*/
|
*/
|
||||||
if( arithmetic->n > MAX_INPUT_IMAGES ) {
|
if( arithmetic->n > MAX_INPUT_IMAGES ) {
|
||||||
|
|
|
@ -492,11 +492,9 @@ vips_foreign_load_start_cb( VipsImage *out, void *a, void *dummy )
|
||||||
/* Read the image in.
|
/* Read the image in.
|
||||||
*/
|
*/
|
||||||
if( class->load( load ) ||
|
if( class->load( load ) ||
|
||||||
vips_image_pio_input( load->real ) ) {
|
vips_image_pio_input( load->real ) )
|
||||||
VIPS_UNREF( load->real );
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return( vips_region_new( load->real ) );
|
return( vips_region_new( load->real ) );
|
||||||
}
|
}
|
||||||
|
@ -530,8 +528,6 @@ vips_foreign_load_build( VipsObject *object )
|
||||||
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( object );
|
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( object );
|
||||||
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( object );
|
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( object );
|
||||||
|
|
||||||
g_object_set( object, "out", vips_image_new(), NULL );
|
|
||||||
|
|
||||||
if( class->get_flags &&
|
if( class->get_flags &&
|
||||||
class->get_flags( load ) )
|
class->get_flags( load ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -540,6 +536,8 @@ vips_foreign_load_build( VipsObject *object )
|
||||||
build( object ) )
|
build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
g_object_set( object, "out", vips_image_new(), NULL );
|
||||||
|
|
||||||
/* Read the header into @out.
|
/* Read the header into @out.
|
||||||
*/
|
*/
|
||||||
if( class->header &&
|
if( class->header &&
|
||||||
|
|
|
@ -483,6 +483,8 @@ void vips_object_sanity_all( void );
|
||||||
|
|
||||||
void vips_object_rewind( VipsObject *object );
|
void vips_object_rewind( VipsObject *object );
|
||||||
|
|
||||||
|
void vips_object_unref_outputs( VipsObject *object );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
|
|
@ -1998,3 +1998,42 @@ vips_object_sanity_all( void )
|
||||||
vips_object_map(
|
vips_object_map(
|
||||||
(VipsSListMap2Fn) vips_object_sanity_all_cb, NULL, NULL );
|
(VipsSListMap2Fn) vips_object_sanity_all_cb, NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vips_object_unref_outputs_sub( VipsObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
VipsArgumentClass *argument_class,
|
||||||
|
VipsArgumentInstance *argument_instance,
|
||||||
|
void *a, void *b )
|
||||||
|
{
|
||||||
|
if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) &&
|
||||||
|
G_IS_PARAM_SPEC_OBJECT( pspec ) &&
|
||||||
|
argument_instance->assigned ) {
|
||||||
|
GObject *value;
|
||||||
|
|
||||||
|
g_object_get( object,
|
||||||
|
g_param_spec_get_name( pspec ), &value, NULL );
|
||||||
|
|
||||||
|
/* Doing the get refs the object, so unref the get, then unref
|
||||||
|
* again since this an an output object of the operation.
|
||||||
|
*/
|
||||||
|
g_object_unref( value );
|
||||||
|
g_object_unref( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unref all assigned output objects.
|
||||||
|
*
|
||||||
|
* After an object is built, all output args are owned by the caller. If
|
||||||
|
* something goes wrong before then, we have to unref the outputs that have
|
||||||
|
* been made so far. And this function can also be useful for callers when
|
||||||
|
* they've finished processing outputs themselves.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vips_object_unref_outputs( VipsObject *object )
|
||||||
|
{
|
||||||
|
(void) vips_argument_map( object,
|
||||||
|
vips_object_unref_outputs_sub, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
|
@ -851,36 +851,12 @@ vips_call_argv_output( VipsObject *object,
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
|
||||||
vips_call_argv_unref_output( VipsObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
VipsArgumentClass *argument_class,
|
|
||||||
VipsArgumentInstance *argument_instance,
|
|
||||||
void *a, void *b )
|
|
||||||
{
|
|
||||||
if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) &&
|
|
||||||
G_IS_PARAM_SPEC_OBJECT( pspec ) &&
|
|
||||||
argument_instance->assigned ) {
|
|
||||||
GObject *value;
|
|
||||||
|
|
||||||
g_object_get( object,
|
|
||||||
g_param_spec_get_name( pspec ), &value, NULL );
|
|
||||||
|
|
||||||
/* Doing the get refs the object, so unref the get, then unref
|
|
||||||
* again since this an an output object of the operation.
|
|
||||||
*/
|
|
||||||
g_object_unref( value );
|
|
||||||
g_object_unref( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Our main command-line entry point. Optional args should have been set by
|
/* Our main command-line entry point. Optional args should have been set by
|
||||||
* the GOption parser already, see above.
|
* the GOption parser already, see above.
|
||||||
*
|
*
|
||||||
* We don't create the operation, so we must not unref it. The caller must
|
* We don't create the operation, so we must not unref it. The caller must
|
||||||
* unref on error too.
|
* unref on error too. The caller must also call vips_object_unref_outputs() on
|
||||||
|
* all code paths.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips_call_argv( VipsOperation *operation, int argc, char **argv )
|
vips_call_argv( VipsOperation *operation, int argc, char **argv )
|
||||||
|
@ -907,15 +883,8 @@ vips_call_argv( VipsOperation *operation, int argc, char **argv )
|
||||||
|
|
||||||
call.i = 0;
|
call.i = 0;
|
||||||
if( vips_argument_map( VIPS_OBJECT( operation ),
|
if( vips_argument_map( VIPS_OBJECT( operation ),
|
||||||
vips_call_argv_input, &call, NULL ) ) {
|
vips_call_argv_input, &call, NULL ) )
|
||||||
/* We must unref any output objects, they are holding refs to
|
|
||||||
* the operation.
|
|
||||||
*/
|
|
||||||
(void) vips_argument_map( VIPS_OBJECT( operation ),
|
|
||||||
vips_call_argv_unref_output, NULL, NULL );
|
|
||||||
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
|
||||||
|
|
||||||
/* Any unused arguments? We must fail. Consider eg. "vips bandjoin a b
|
/* Any unused arguments? We must fail. Consider eg. "vips bandjoin a b
|
||||||
* c". This would overwrite b with a and ignore c, potentially
|
* c". This would overwrite b with a and ignore c, potentially
|
||||||
|
@ -924,37 +893,16 @@ vips_call_argv( VipsOperation *operation, int argc, char **argv )
|
||||||
if( argc > call.i ) {
|
if( argc > call.i ) {
|
||||||
vips_error( VIPS_OBJECT_GET_CLASS( operation )->nickname,
|
vips_error( VIPS_OBJECT_GET_CLASS( operation )->nickname,
|
||||||
"%s", _( "too many arguments" ) );
|
"%s", _( "too many arguments" ) );
|
||||||
|
|
||||||
/* We must unref any output objects, they are holding refs to
|
|
||||||
* the operation.
|
|
||||||
*/
|
|
||||||
(void) vips_argument_map( VIPS_OBJECT( operation ),
|
|
||||||
vips_call_argv_unref_output, NULL, NULL );
|
|
||||||
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( vips_object_build( VIPS_OBJECT( operation ) ) ) {
|
if( vips_object_build( VIPS_OBJECT( operation ) ) )
|
||||||
/* We must unref any output objects, they are holding refs to
|
|
||||||
* the operation.
|
|
||||||
*/
|
|
||||||
(void) vips_argument_map( VIPS_OBJECT( operation ),
|
|
||||||
vips_call_argv_unref_output, NULL, NULL );
|
|
||||||
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
|
||||||
|
|
||||||
call.i = 0;
|
call.i = 0;
|
||||||
if( vips_argument_map( VIPS_OBJECT( operation ),
|
if( vips_argument_map( VIPS_OBJECT( operation ),
|
||||||
vips_call_argv_output, &call, NULL ) ) {
|
vips_call_argv_output, &call, NULL ) )
|
||||||
(void) vips_argument_map( VIPS_OBJECT( operation ),
|
|
||||||
vips_call_argv_unref_output, NULL, NULL );
|
|
||||||
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
|
||||||
|
|
||||||
(void) vips_argument_map( VIPS_OBJECT( operation ),
|
|
||||||
vips_call_argv_unref_output, NULL, NULL );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1075,10 +1075,13 @@ main( int argc, char **argv )
|
||||||
if( argc == 1 )
|
if( argc == 1 )
|
||||||
vips_object_print( VIPS_OBJECT( operation ) );
|
vips_object_print( VIPS_OBJECT( operation ) );
|
||||||
|
|
||||||
|
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
||||||
g_object_unref( operation );
|
g_object_unref( operation );
|
||||||
|
|
||||||
error_exit( NULL );
|
error_exit( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
||||||
g_object_unref( operation );
|
g_object_unref( operation );
|
||||||
|
|
||||||
handled = TRUE;
|
handled = TRUE;
|
||||||
|
|
Loading…
Reference in New Issue