#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的更多相关文章

  1. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

  2. Java开发中的23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  3. java中的23中设计模式(转)

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  4. Python 程序员经常犯的 10 个错误

    关于PythonPython是一种解释性.面向对象并具有动态语义的高级程序语言.它内建了高级的数据结构,结合了动态类型和动态绑定的优点,这使得... 关于Python Python是一种解释性.面向对 ...

  5. xml文档解析

    XML文档解主要分为四种解析方式,官方提供的两种分别是:DOM 和 SAX,第三方分别是:JDOM 和 DOM4j 测试用的xml文档: <?xml version="1.0" ...

  6. 转:python signal信号

    转自:http://www.jb51.net/article/74844.htm 在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点 ...

  7. java开发中的23中设计模式详解--大话设计模式

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  8. java基础语法要点<一>(基于1.8)

    http://yishouce.com/java/run http://www.shucunwang.com/RunCode/java/ 数据类型 8种基本数据类型及对应的 类型封装器 byte, s ...

  9. Python开发最常犯错误总结10种

    不管是在学习还是工作过程中,人都会犯错.虽然Python的语法简单.灵活,但也一样存在一些不小的坑,一不小心,初学者和资深Python程序员都有可能会栽跟头.本文是Toptal网站的程序员梳理的10大 ...

随机推荐

  1. pure virtual function call

    2015-04-08 10:58:19 基类中定义了纯虚函数,派生类中将其实现. 如果在基类的构造函数或者析构函数中调用了改纯虚函数, 则会出现R6205 Error: pure virtual fu ...

  2. Jmeter从数据库获取数据当做变量,传递给其他接口

    1.添加JDBC Request 2.JDBC的配置,Variable名字和之前的数据库配置的名字一致,生成的变量放在下面的Variable name

  3. 关于去除Eclipse对JavaScript的验证

    关于去除Eclipse对JavaScript的验证 在我们使用大量JavaScript作为一些UI或其他组件来使用时,很多情况下,明明引用的这些JavaScript是可以正常使用的,但Eclipse却 ...

  4. [翻译]lithium 安装

    安装 要求 web服务器 你需要一个web服务器来运行你的应用,最好是可以运行在你的本地机器上(你所有的开发不是都在这上面做的吗,不是吗?不是吗?).对于PHP而言,框架在很多web服务器上都运行的很 ...

  5. java.lang.classNotFound:明明已经导入了jar包,包里也有该类,却找不到的解决方法

    试一下:在web-inf文件夹下新建lib文件夹:将所有需要用到的jar包放在lib中,重启tomcat.

  6. phpstrom正则替换

  7. JavaScript的chapterIII

    七.函数 函数由关键字function + 函数名 + 一组参数定义 函数可以被反复调用 语法: function funName( arg0,arg1,... argN){ statements; ...

  8. Spark学习(二) -- Spark整体框架

    标签(空格分隔): Spark 还记得上次的wordCount程序嘛?通过这个小程序,我们来一窥Spark的框架是什么样子的. sc.textFile("/usr/local/Cellar/ ...

  9. MyEclipse中的SVN操作手册

    原文出处:http://blog.sina.com.cn/s/blog_8a3d83320100zhmp.html 1.导入项目 点击工具栏上的[File-Import],进入下图 (如果你的对话框中 ...

  10. quantile normalization原理

    对于芯片或者其它表达数据来说,最常见的莫过于quantile normalization啦. 那么它到底对我们的表达数据做了什么呢?首先要么要清楚一个概念,表达矩阵的每一列都是一个样本,每一行都是一个 ...