myhandle
#ifndef my_handle_h
#define my_handle_h #include <stdint.h>
#include "mydef.h"
#include "mem.h" typedef struct tag_my_handle {
int ref;
int stack;
intptr_t detached;
void* ptr;
free_t free;
} my_handle; static inline my_handle* debug_handle_attach(void* ptr, free_t fp_free, const char* func, int line)
{
my_handle* handle = (my_handle *) debug_malloc(sizeof(my_handle), func, line);
if (handle != NULL) {
handle->ref = 1;
handle->stack = 1; handle->ptr = ptr;
handle->free = fp_free;
handle->detached = 0;
}
return handle;
}
#define handle_attach(ptr, fptr) debug_handle_attach(ptr, fptr, __FUNCTION__, __LINE__) #define handle_put(handle) \
do { \
int n = __sync_sub_and_fetch(&(handle)->stack, 1); \
my_assert(n >= 0); \
if (n == 0) { \
void* handle_ptr = (void *) __sync_lock_test_and_set(&(handle)->ptr, NULL); \
if ((handle)->free && handle_ptr) { \
(handle)->free(handle_ptr); \
} \
} \
} while (0) static inline void* handle_get_with(my_handle* handle, int detach, const char* func, int line)
{
int n = __sync_add_and_fetch(&handle->stack, 1);
int b = __sync_bool_compare_and_swap((void **) &handle->detached, (void *) 0, (void *) (intptr_t) detach);
if (!b) {
handle_put(handle);
return NULL;
} void* ptr = handle->ptr;
my_assert2(n > 1 && ptr != NULL, "%d, %p, caller %d@%s", n, ptr, line, func);
return ptr;
}
#define handle_get(handle) handle_get_with((handle), 0, __FUNCTION__, __LINE__) static inline int handle_clone(my_handle* handle)
{
int n = __sync_add_and_fetch(&handle->ref, 1);
my_assert(n > 0);
return n;
} static inline int handle_release(my_handle* handle)
{
int n = __sync_sub_and_fetch(&handle->ref, 1);
my_assert2(n >= 0, "%p %d:%d", handle, handle->ref, handle->stack);
if (n > 0) {
return n;
} // it should be safe to simplely check whether detached equals 0.
// we know __sync_xxx functions have mb() semantics, and
// if some one set handle->detached = 1, it only can be called in
// handle_dettach while still holds a reference of handle.
// ok, now we have seen handle->ref = 0 above, meaning
// we have observed the latter handle_release in handle_dettach.
// then, the mb() assure that
// we have observed the earlier handle_get_with(handle, 1).
if (handle->detached == 0) {
handle_put(handle);
}
my_assert(handle->stack == 0); my_free(handle);
return n;
} static inline int debug_handle_dettach(my_handle* handle, const char* func, int line)
{
void* ptr = handle_get_with(handle, 1, func, line);
if (ptr != NULL) {
__sync_sub_and_fetch(&handle->stack, 1);
handle_put(handle);
}
return handle_release(handle);
}
#define handle_dettach(handle) debug_handle_dettach((handle), __FUNCTION__, __LINE__) #endif
myhandle的更多相关文章
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- Java开发中的23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- java中的23中设计模式(转)
设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- Python 程序员经常犯的 10 个错误
关于PythonPython是一种解释性.面向对象并具有动态语义的高级程序语言.它内建了高级的数据结构,结合了动态类型和动态绑定的优点,这使得... 关于Python Python是一种解释性.面向对 ...
- xml文档解析
XML文档解主要分为四种解析方式,官方提供的两种分别是:DOM 和 SAX,第三方分别是:JDOM 和 DOM4j 测试用的xml文档: <?xml version="1.0" ...
- 转:python signal信号
转自:http://www.jb51.net/article/74844.htm 在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点 ...
- java开发中的23中设计模式详解--大话设计模式
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- java基础语法要点<一>(基于1.8)
http://yishouce.com/java/run http://www.shucunwang.com/RunCode/java/ 数据类型 8种基本数据类型及对应的 类型封装器 byte, s ...
- Python开发最常犯错误总结10种
不管是在学习还是工作过程中,人都会犯错.虽然Python的语法简单.灵活,但也一样存在一些不小的坑,一不小心,初学者和资深Python程序员都有可能会栽跟头.本文是Toptal网站的程序员梳理的10大 ...
随机推荐
- Spring MVC中Action使用总结
Spring MVC中每个控制器中可以定义多个请求处理方法即Action,Action可以有多个不同的参数,有多种类型的返回结果. 可以作为Action的参数类型有: 表单对象基本数据类型,包括包装类 ...
- Spring MVC控制器
Spring MVC中控制器用于解析用户请求并且转换为模型以提供访问应用程序的行为,通常用注解方式实现. org.springframework.stereotype.Controller注解用于声明 ...
- mysql实战之 批量update
mysql实战之批量update 现阶段我们的业务量很小,要对admin_user表中的relationship字段进行更新,指定id是409.已知409是公司内的一服务中心,需要把该服务中心放到区代 ...
- maven创建子项目(适用于多模块管理项目)
在eclipse或者myeclipse下构建maven项目,该项目由多个子模块组成. 1.创建一个父项目 NEW -->project-->maven-->maven Project ...
- Android SDK Tools 更新
C:\WINDOWS\system32\drivers\etc\hosts 文件用记事本打开后 添加下面的 74.125.237.1 dl-ssl.google.com
- 为什么当多个inline-block的div中,如果有的div没有内容而有的div有内容,有内容的会下沉?
为什么当多个inline-block的div中,如果有的div没有内容而有的div有内容,有内容的会下沉? 就像这样 两个div高度相同,第二个我写了一个1当作 有内容吧,它就下沉了... 奇怪... ...
- 企业办公3D指纹考勤系统解决方案
员工准时.正常出勤是企业考勤制度的基本要求,然而目前签名式.卡钟式.IC卡考勤系统均存在代打卡.人情卡.不易统计等漏洞,而市面上的光学指纹考勤机存在识别能力差.识别速度慢.使用寿命短.不能完全杜绝指纹 ...
- exel按行查找或按列查找
表1:sheet1 1). 在表1中找出ID号位0928的基因相对应的数值 在相对应的单元格输入:B2=VLOOKUP(A:A,Sheet1!A:D,3,0) 既可以得到: ············· ...
- JS中函数声明与函数表达式的不同
Js中的函数声明是指下面的形式: function functionName(){ } 这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如 var functionName ...
- smarty模板中如何嵌入javascript脚本
[官方网站](http://www.php100.com/manual/smarty/) 在smarty文件里直接写javascript代码时候,造成500错误. javascript代码有很多的{} ...