zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    Ceph的参数mon_osd_down_out_subtree_limit细解
    java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查
    Java 原始类型JComboBox的成员JComboBox(E())的调用 未经过检查
    Android draw Rect 坐标图示
    不用快捷键就能使用Eclipse的自动完成功能
    Java 窗体居中 通用代码
    Java文件复制删除操作合集
    Java Toolkit类用法
    DEVEXPRESS 破解方法
    如何使用Java执行cmd命令
  • 原文地址:https://www.cnblogs.com/zylthinking/p/5975721.html
Copyright © 2011-2022 走看看