Function encapsulation technique--function pointer+void*variable

Article Directory

Preface

The first step in the learning of all techniques is to organize the postures first, and then learn the internal merits after being skilled in the postures.Finally, blend through.This time I'll clean up the use of function pointers in company code.

Step 1: Define a callback function

Be aware:
1. The input parameter is of void * type. This has the advantage that if you want to pass in only one parameter in the future, char * can be turned strong directly. If more than one parameter is involved, you can define a structure to go in and truly make the function universal.
2. Output parameter is void ** Benefit of course, it is completely self-defined
3. The following function pointers are very versatile

typedef int (*hikos_callback) (
    enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer);

Step 2: Common functions call callback functions

1. Define a common function to call the function pointer mentioned above, which allows multiple teams to work together to develop
2. The subsequent parameters of the common function are all parameters of the function pointer.

ret = hikos_storage(hikos_ceph, global_action, global_command, global_inbuffer, (void *)&outbuffer);

Common Function Function Implementation

int hikos_storage(hikos_callback callback_f, 
    enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer)
{
    int ret = 0;
    int fd = -1;
    int file_seek = 0;
    cs_file_t *p_cs_file = NULL;

    int action_value = 0;
    long command_value = 0;
    char command_str[64] = {0};

    p_cs_file = malloc(sizeof(cs_file_t));
    if (!p_cs_file)
    {
        common_print(PRINT_ALERT, "malloc error");
        ret = ERROR_MALLOC;
        goto out;
    }
    memset(p_cs_file, 0, sizeof(cs_file_t));

    fd = open(STORAGE_CS_PATH, O_RDONLY);
    if (-1 == fd)
    {
        common_print(PRINT_ALERT, "%s: open error", STORAGE_CS_PATH);
        ret = ERROR_PATH;
        goto out;
    }

    flock(fd, LOCK_EX);

    while (sizeof(cs_file_t) == pread(fd, p_cs_file, sizeof(cs_file_t), file_seek)) 
    {
        if (!strcmp(p_cs_file->api_action, "get")) 
        {
            action_value = STORAGE_ACTION_GET;
        } 
        else if (!strcmp(p_cs_file->api_action, "add")) 
        {
            action_value = STORAGE_ACTION_ADD;
        } 
        else if (!strcmp(p_cs_file->api_action, "set")) 
        {
            action_value = STORAGE_ACTION_SET;
        } 
        else if (!strcmp(p_cs_file->api_action, "del")) 
        {
            action_value = STORAGE_ACTION_DEL;
        } 
        else if (!strcmp(p_cs_file->api_action, "chk")) 
        {
            action_value = STORAGE_ACTION_CHK;
        }

        sscanf(p_cs_file->api_command, "%lx:%s", &command_value, command_str);
        
        if (action_e == action_value && id == command_value) 
        {
            if (1 == p_cs_file->api_enable)
            {
                flock(fd, LOCK_UN);

                ret = callback_f(action_e, id, inbuffer, (void *)outbuffer);

                goto out;
            }
            else
            {
                ret = ERROR_DISABLE;
            }
            
            break;
        }
        
        file_seek += sizeof(cs_file_t);
        memset(p_cs_file, 0, sizeof(cs_file_t));
    }

    flock(fd, LOCK_UN);
    
    out:
        if (-1 != fd)
        {
            close(fd);
            fd = -1;
        }

        if (p_cs_file)
        {
            free(p_cs_file);
            p_cs_file = NULL;
        }
        
        return ret;        
}

Step 3: Examine one of the group sub-modules

1. Use enumeration to control functional classification

int hikos_ceph(
    enum storage_action_e action_e, const long id, void *inbuffer, void **outbuffer)
{
    int ret = -1;

    switch (action_e)
    {
        case STORAGE_ACTION_GET:       
            ret = ceph_get(id, inbuffer, outbuffer);
            break;
        case STORAGE_ACTION_ADD:
            ret = ceph_add(id, inbuffer, outbuffer);
            break;
        case STORAGE_ACTION_SET:
            ret = ceph_set(id, inbuffer, outbuffer);
            break;
        case STORAGE_ACTION_DEL:
            ret = ceph_del(id, inbuffer, outbuffer);
            break;
        case STORAGE_ACTION_CHK:
            ret = ceph_chk(id, inbuffer, outbuffer);
            break;
        default:
            goto out;
    }
    
    return ret;

    out:
        return ret;
}

Step 4: Reuse id to control the development of team members

static int  ceph_add(const long id, void *inbuffer, void **outbuffer)
{
    int ret = -1;

    switch (id)
    {
        case 0x00112000:
            break;

        case CEPH_CLUSTER_ADD_NODE:	
            ret = ceph_add_node(inbuffer, outbuffer);
            break;

        case CEPH_POOL_CREATE: 
            ret = ceph_pool_create(inbuffer,NULL);
            break;
            
        case CEPH_POOL_EXPAND:
            ret = ceph_pool_expand(inbuffer,NULL);
            break; 
            
        default:
            ret = ERROR_UNKNOW;
            goto out;
    }
    return ret;

    out:
        return ret;
}
/* ceph Module Commands */
typedef enum 
{
    CEPH_RPM_INSTALL = 0x00130000,           /*Install the ceph rpm package*/
    CEPH_RPM_STATUS,                                 /*ceph Installation Package Status*/
    CEPH_CLUSTER_CREATE,                          /*ceph Cluster creation*/
    CEPH_CLUSTER_ADD_NODE,                      /*ceph Cluster Expansion*/
    CEPH_CLUSTER_CREATE_PRO,
    CEPH_CLUSTER_ADD_NODE_PRO,
    CEPH_PURE_DEPLOY_PROGRESS,
    CEPH_CLUSTER_ERROR = 0x00130FFF,

    CEPH_DISK_GET_DISK_LIST = 0x00131000,    /*Get a list of available disks for ceph*/
    CEPH_DISK_DEL_POOL_DISK,			     /*Remove disks from storage pool*/
    CEPH_DISK_GET_OSD_INFO,		            /*Get osd status information*/
    CEPH_DISK_ERROR = 0x00131FFF,	            /* Unknown command code*/ 

    CEPH_POOL_CREATE = 0x00132001,              /*ceph Storage pool creation*/
    CEPH_POOL_EXPAND,                                   /* ceph Storage pool expansion*/
    CEPH_POOL_LIST,                                         /*ceph Storage pool list*/
    CEPH_POOL_DETAIL,                                     /*ceph Storage pool details*/
    CEPH_POOL_DELETE,                                    /*ceph Delete Storage Pool*/
    CEPH_POOL_PERFORMANCE,                          /*pool Performance Collection*/ 
    CEPH_POOL_PROGRESS,                             /*Progress information*/
    CEPH_POOL_ERROR = 0x00132FFF,

    CEPH_ALARM_CLUSTER = 0x00133001,        /* ceph Cluster Alert */
    CEPH_ALARM_CAPACITY,                            /* ceph Capacity Alert */
    CEPH_ALARM_ERROR = 0x00133FFF    
}CEPH_COMMAND_E;
164 original articles published. 6. 7,644 visits
Private letter follow

Tags: Ceph RPM osd

Posted on Sun, 26 Jan 2020 21:00:25 -0500 by faza