/** @internal * Function oyProfileTag_Release_ * @memberof oyProfileTag_s_ * @brief release and possibly deallocate a ProfileTag object * * @param[in,out] profiletag ProfileTag struct object * * @version Oyranos: * @since 2010/04/26 (Oyranos: 0.1.10) * @date 2010/04/26 */ int oyProfileTag_Release_( oyProfileTag_s_ **profiletag ) { /* ---- start of common object destructor ----- */ oyProfileTag_s_ *s = 0; if(!profiletag || !*profiletag) return 0; s = *profiletag; *profiletag = 0; if(oyObject_UnRef(s->oy_)) return 0; /* ---- end of common object destructor ------- */ /* ---- start of custom ProfileTag destructor ----- */ oyProfileTag_Release__Members( s ); /* ---- end of custom ProfileTag destructor ------- */ if(s->oy_->deallocateFunc_) { oyDeAlloc_f deallocateFunc = s->oy_->deallocateFunc_; oyObject_Release( &s->oy_ ); deallocateFunc( s ); } return 0; }
/** @internal * Function oyOption_Release_ * @memberof oyOption_s_ * @brief release and possibly deallocate a Option object * * @param[in,out] option Option struct object * * @version Oyranos: * @since 2010/04/26 (Oyranos: 0.1.10) * @date 2010/04/26 */ int oyOption_Release_( oyOption_s_ **option ) { /* ---- start of common object destructor ----- */ oyOption_s_ *s = 0; if(!option || !*option) return 0; s = *option; *option = 0; if(oyObject_UnRef(s->oy_)) return 0; /* ---- end of common object destructor ------- */ /* ---- start of custom Option destructor ----- */ oyOption_Release__Members( s ); /* ---- end of custom Option destructor ------- */ if(s->oy_->deallocateFunc_) { oyDeAlloc_f deallocateFunc = s->oy_->deallocateFunc_; oyObject_Release( &s->oy_ ); deallocateFunc( s ); } return 0; }
/** @internal * Function oyNamedColor_Release_ * @memberof oyNamedColor_s_ * @brief release and possibly deallocate a NamedColor object * * @param[in,out] namedcolor NamedColor struct object * * @version Oyranos: * @since 2010/04/26 (Oyranos: 0.1.10) * @date 2010/04/26 */ int oyNamedColor_Release_( oyNamedColor_s_ **namedcolor ) { /* ---- start of common object destructor ----- */ oyNamedColor_s_ *s = 0; if(!namedcolor || !*namedcolor) return 0; s = *namedcolor; *namedcolor = 0; if(oyObject_UnRef(s->oy_)) return 0; /* ---- end of common object destructor ------- */ /* ---- start of custom NamedColor destructor ----- */ oyNamedColor_Release__Members( s ); /* ---- end of custom NamedColor destructor ------- */ if(s->oy_->deallocateFunc_) { oyDeAlloc_f deallocateFunc = s->oy_->deallocateFunc_; oyObject_Release( &s->oy_ ); deallocateFunc( s ); } return 0; }
/** @internal * Function oyFilterGraph_Release_ * @memberof oyFilterGraph_s_ * @brief release and possibly deallocate a FilterGraph object * * @param[in,out] filtergraph FilterGraph struct object * * @version Oyranos: 0.9.7 * @date 2018/10/03 * @since 2010/04/26 (Oyranos: 0.1.10) */ int oyFilterGraph_Release_( oyFilterGraph_s_ **filtergraph ) { const char * track_name = NULL; int observer_refs = 0, i; /* ---- start of common object destructor ----- */ oyFilterGraph_s_ *s = 0; if(!filtergraph || !*filtergraph) return 0; s = *filtergraph; /* static object */ if(!s->oy_) return 0; *filtergraph = 0; observer_refs = oyStruct_ObservationCount( (oyStruct_s*)s, 0 ); if(oy_debug_objects >= 0) { const char * t = getenv(OY_DEBUG_OBJECTS); int id_ = -1; if(t) id_ = atoi(t); else id_ = oy_debug_objects; if((id_ >= 0 && s->oy_->id_ == id_) || (t && (strstr(oyStructTypeToText(s->type_), t) != 0)) || id_ == 1) { oyStruct_s ** parents = NULL; int n = oyStruct_GetParents( (oyStruct_s*)s, &parents ); if(n != s->oy_->ref_) { int i; #ifdef HAVE_BACKTRACE int j, nptrs; void *buffer[BT_BUF_SIZE]; char **strings; nptrs = backtrace(buffer, BT_BUF_SIZE); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if( strings == NULL ) { perror("backtrace_symbols"); } else { int start = nptrs-1; do { --start; } while( start >= 0 && (strstr(strings[start], "(main+") == NULL) ); fprintf(stderr, "\n"); for(j = start; j >= 0; j--) { if(oy_debug) fprintf(stderr, "%s\n", strings[j]); else { char * t = NULL, * txt = NULL; const char * line = strings[j], * tmp = strchr( line, '(' ); if(tmp) t = oyStringCopy( &tmp[1], NULL ); else t = oyStringCopy( line, NULL ); txt = strchr( t, '+' ); if(txt) txt[0] = '\000'; if(j > 0 && (strstr(strings[j-1], t) != NULL) ) oyFree_m_(t); if(t) { if(j==0) fprintf(stderr, "%s() ", t); else fprintf(stderr, "%s()->", t); oyFree_m_(t); } } } free(strings); } #endif track_name = oyStructTypeToText(s->type_); fprintf( stderr, "%s[%d] unref with refs: %d observers: %d parents: %d\n", track_name, s->oy_->id_, s->oy_->ref_, observer_refs, n ); for(i = 0; i < n; ++i) { track_name = oyStructTypeToText(parents[i]->type_); fprintf( stderr, "parent[%d]: %s[%d]\n", i, track_name, parents[i]->oy_->id_ ); } } } } if((oyObject_UnRef(s->oy_) - observer_refs) > 0) return 0; /* ---- end of common object destructor ------- */ if(oy_debug_objects >= 0) { const char * t = getenv(OY_DEBUG_OBJECTS); int id_ = -1; if(t) id_ = atoi(t); else id_ = oy_debug_objects; if((id_ >= 0 && s->oy_->id_ == id_) || (t && s && (strstr(oyStructTypeToText(s->type_), t) != 0)) || id_ == 1) { track_name = oyStructTypeToText(s->type_); fprintf( stderr, "%s[%d] destruct\n", track_name, s->oy_->id_); } } /* ---- start of custom FilterGraph destructor ----- */ oyFilterGraph_Release__Members( s ); /* ---- end of custom FilterGraph destructor ------- */ /* model and observer reference each other. So release the object two times. * The models and and observers are released later inside the * oyObject_s::handles. */ for(i = 0; i < observer_refs; ++i) { oyObject_UnRef(s->oy_); oyObject_UnRef(s->oy_); } if(s->oy_->deallocateFunc_) { oyDeAlloc_f deallocateFunc = s->oy_->deallocateFunc_; int id = s->oy_->id_; int refs = s->oy_->ref_; if(refs > 1) fprintf( stderr, "!!!ERROR: node[%d]->object can not be untracked with refs: %d\n", id, refs); oyObject_Release( &s->oy_ ); if(track_name) fprintf( stderr, "%s[%d] destructed\n", track_name, id ); deallocateFunc( s ); } return 0; }