⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 talloc.c

📁 samba服务器!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  remove a secondary reference to a pointer. This undo's what  talloc_reference() has done. The context and pointer arguments  must match those given to a talloc_reference()*/static inline int talloc_unreference(const void *context, const void *ptr){	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);	struct talloc_reference_handle *h;	if (unlikely(context == NULL)) {		context = null_context;	}	for (h=tc->refs;h;h=h->next) {		struct talloc_chunk *p = talloc_parent_chunk(h);		if (p == NULL) {			if (context == NULL) break;		} else if (TC_PTR_FROM_CHUNK(p) == context) {			break;		}	}	if (h == NULL) {		return -1;	}	return _talloc_free(h);}/*  remove a specific parent context from a pointer. This is a more  controlled varient of talloc_free()*/int talloc_unlink(const void *context, void *ptr){	struct talloc_chunk *tc_p, *new_p;	void *new_parent;	if (ptr == NULL) {		return -1;	}	if (context == NULL) {		context = null_context;	}	if (talloc_unreference(context, ptr) == 0) {		return 0;	}	if (context == NULL) {		if (talloc_parent_chunk(ptr) != NULL) {			return -1;		}	} else {		if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {			return -1;		}	}		tc_p = talloc_chunk_from_ptr(ptr);	if (tc_p->refs == NULL) {		return _talloc_free(ptr);	}	new_p = talloc_parent_chunk(tc_p->refs);	if (new_p) {		new_parent = TC_PTR_FROM_CHUNK(new_p);	} else {		new_parent = NULL;	}	if (talloc_unreference(new_parent, ptr) != 0) {		return -1;	}	talloc_steal(new_parent, ptr);	return 0;}/*  add a name to an existing pointer - va_list version*/static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap){	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);	tc->name = talloc_vasprintf(ptr, fmt, ap);	if (likely(tc->name)) {		_talloc_set_name_const(tc->name, ".name");	}	return tc->name;}/*  add a name to an existing pointer*/const char *talloc_set_name(const void *ptr, const char *fmt, ...){	const char *name;	va_list ap;	va_start(ap, fmt);	name = talloc_set_name_v(ptr, fmt, ap);	va_end(ap);	return name;}/*  create a named talloc pointer. Any talloc pointer can be named, and  talloc_named() operates just like talloc() except that it allows you  to name the pointer.*/void *talloc_named(const void *context, size_t size, const char *fmt, ...){	va_list ap;	void *ptr;	const char *name;	ptr = __talloc(context, size);	if (unlikely(ptr == NULL)) return NULL;	va_start(ap, fmt);	name = talloc_set_name_v(ptr, fmt, ap);	va_end(ap);	if (unlikely(name == NULL)) {		_talloc_free(ptr);		return NULL;	}	return ptr;}/*  return the name of a talloc ptr, or "UNNAMED"*/const char *talloc_get_name(const void *ptr){	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);	if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {		return ".reference";	}	if (likely(tc->name)) {		return tc->name;	}	return "UNNAMED";}/*  check if a pointer has the given name. If it does, return the pointer,  otherwise return NULL*/void *talloc_check_name(const void *ptr, const char *name){	const char *pname;	if (unlikely(ptr == NULL)) return NULL;	pname = talloc_get_name(ptr);	if (likely(pname == name || strcmp(pname, name) == 0)) {		return discard_const_p(void, ptr);	}	return NULL;}/*  this is for compatibility with older versions of talloc*/void *talloc_init(const char *fmt, ...){	va_list ap;	void *ptr;	const char *name;	/*	 * samba3 expects talloc_report_depth_cb(NULL, ...)	 * reports all talloc'ed memory, so we need to enable	 * null_tracking	 */	talloc_enable_null_tracking();	ptr = __talloc(NULL, 0);	if (unlikely(ptr == NULL)) return NULL;	va_start(ap, fmt);	name = talloc_set_name_v(ptr, fmt, ap);	va_end(ap);	if (unlikely(name == NULL)) {		_talloc_free(ptr);		return NULL;	}	return ptr;}/*  this is a replacement for the Samba3 talloc_destroy_pool functionality. It  should probably not be used in new code. It's in here to keep the talloc  code consistent across Samba 3 and 4.*/void talloc_free_children(void *ptr){	struct talloc_chunk *tc;	if (unlikely(ptr == NULL)) {		return;	}	tc = talloc_chunk_from_ptr(ptr);	while (tc->child) {		/* we need to work out who will own an abandoned child		   if it cannot be freed. In priority order, the first		   choice is owner of any remaining reference to this		   pointer, the second choice is our parent, and the		   final choice is the null context. */		void *child = TC_PTR_FROM_CHUNK(tc->child);		const void *new_parent = null_context;		if (unlikely(tc->child->refs)) {			struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);			if (p) new_parent = TC_PTR_FROM_CHUNK(p);		}		if (unlikely(_talloc_free(child) == -1)) {			if (new_parent == null_context) {				struct talloc_chunk *p = talloc_parent_chunk(ptr);				if (p) new_parent = TC_PTR_FROM_CHUNK(p);			}			talloc_steal(new_parent, child);		}	}}/*    Allocate a bit of memory as a child of an existing pointer*/void *_talloc(const void *context, size_t size){	return __talloc(context, size);}/*  externally callable talloc_set_name_const()*/void talloc_set_name_const(const void *ptr, const char *name){	_talloc_set_name_const(ptr, name);}/*  create a named talloc pointer. Any talloc pointer can be named, and  talloc_named() operates just like talloc() except that it allows you  to name the pointer.*/void *talloc_named_const(const void *context, size_t size, const char *name){	return _talloc_named_const(context, size, name);}/*    free a talloc pointer. This also frees all child pointers of this    pointer recursively   return 0 if the memory is actually freed, otherwise -1. The memory   will not be freed if the ref_count is > 1 or the destructor (if   any) returns non-zero*/int talloc_free(void *ptr){	return _talloc_free(ptr);}/*  A talloc version of realloc. The context argument is only used if  ptr is NULL*/void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name){	struct talloc_chunk *tc;	void *new_ptr;	/* size zero is equivalent to free() */	if (unlikely(size == 0)) {		_talloc_free(ptr);		return NULL;	}	if (unlikely(size >= MAX_TALLOC_SIZE)) {		return NULL;	}	/* realloc(NULL) is equivalent to malloc() */	if (ptr == NULL) {		return _talloc_named_const(context, size, name);	}	tc = talloc_chunk_from_ptr(ptr);	/* don't allow realloc on referenced pointers */	if (unlikely(tc->refs)) {		return NULL;	}	/* by resetting magic we catch users of the old memory */	tc->flags |= TALLOC_FLAG_FREE;#if ALWAYS_REALLOC	new_ptr = malloc(size + TC_HDR_SIZE);	if (new_ptr) {		memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);		free(tc);	}#else	new_ptr = realloc(tc, size + TC_HDR_SIZE);#endif	if (unlikely(!new_ptr)) {			tc->flags &= ~TALLOC_FLAG_FREE; 		return NULL; 	}	tc = (struct talloc_chunk *)new_ptr;	tc->flags &= ~TALLOC_FLAG_FREE; 	if (tc->parent) {		tc->parent->child = tc;	}	if (tc->child) {		tc->child->parent = tc;	}	if (tc->prev) {		tc->prev->next = tc;	}	if (tc->next) {		tc->next->prev = tc;	}	tc->size = size;	_talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);	return TC_PTR_FROM_CHUNK(tc);}/*  a wrapper around talloc_steal() for situations where you are moving a pointer  between two structures, and want the old pointer to be set to NULL*/void *_talloc_move(const void *new_ctx, const void *_pptr){	const void **pptr = discard_const_p(const void *,_pptr);	void *ret = _talloc_steal(new_ctx, *pptr);	(*pptr) = NULL;	return ret;}/*  return the total size of a talloc pool (subtree)*/size_t talloc_total_size(const void *ptr){	size_t total = 0;	struct talloc_chunk *c, *tc;	if (ptr == NULL) {		ptr = null_context;	}	if (ptr == NULL) {		return 0;	}	tc = talloc_chunk_from_ptr(ptr);	if (tc->flags & TALLOC_FLAG_LOOP) {		return 0;	}	tc->flags |= TALLOC_FLAG_LOOP;	total = tc->size;	for (c=tc->child;c;c=c->next) {		total += talloc_total_size(TC_PTR_FROM_CHUNK(c));	}	tc->flags &= ~TALLOC_FLAG_LOOP;	return total;}/*  return the total number of blocks in a talloc pool (subtree)*/size_t talloc_total_blocks(const void *ptr){	size_t total = 0;	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);	if (tc->flags & TALLOC_FLAG_LOOP) {		return 0;	}	tc->flags |= TALLOC_FLAG_LOOP;	total++;	for (c=tc->child;c;c=c->next) {		total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));	}	tc->flags &= ~TALLOC_FLAG_LOOP;	return total;}/*  return the number of external references to a pointer*/size_t talloc_reference_count(const void *ptr){	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);	struct talloc_reference_handle *h;	size_t ret = 0;	for (h=tc->refs;h;h=h->next) {		ret++;	}	return ret;}/*  report on memory usage by all children of a pointer, giving a full tree view*/void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,			    void (*callback)(const void *ptr,			  		     int depth, int max_depth,					     int is_ref,					     void *private_data),			    void *private_data){	struct talloc_chunk *c, *tc;	if (ptr == NULL) {		ptr = null_context;	}	if (ptr == NULL) return;	tc = talloc_chunk_from_ptr(ptr);	if (tc->flags & TALLOC_FLAG_LOOP) {		return;	}	callback(ptr, depth, max_depth, 0, private_data);	if (max_depth >= 0 && depth >= max_depth) {		return;	}	tc->flags |= TALLOC_FLAG_LOOP;	for (c=tc->child;c;c=c->next) {		if (c->name == TALLOC_MAGIC_REFERENCE) {			struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);			callback(h->ptr, depth + 1, max_depth, 1, private_data);		} else {			talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);		}	}	tc->flags &= ~TALLOC_FLAG_LOOP;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -