Previous: Referable Queue Declarable Data Type Definition, Up: Complex Referable Data Type Example


3.4.2.3 Referable Queue Referable Data Type Definition

The referable object data types definition:

See struct x1f4_nodetype_type.

struct x1f4_nodetype_type node_type = {
    "decq",
    HERE_DECQ,
    copy_decq,
    free_decq,
    move_decq,
    node_decq,
    post_decq,
    push_decq,
    X1f4_LX_LINK_ACCESS | X1f4_LX_POST_ACCESS,
    4,
    NULL
};

The definition restates the 4 characters long `decq' name and the HERE_DECQ id for the data type.

The X1f4_LX_LINK_ACCESS indicates that the node field is set (here to some node_decq routine) and to be used.

The X1f4_LX_POST_ACCESS indicates that the post field is set (here to some post_decq routine) and to be used.

See Common Data Type Flags.

The routine copying some queue object and setting it referred by some object:

int
copy_decq(void *context, void *subtext, void **copy,
	  const struct x1f4_nodelink_type *nodelink_data)
{
    int status;
    struct this_type *this_data;

    allocate memory for data, copy the actual queue object, set status to
    operation success

    if (status) {
    } else {
	this_data->node.call = 1;

	setup the this_data->node.pset pointer set, set status to operation
	success

	if (status) {
	    dispose of the actual queue object, free memory for data
	} else {
	    this_data->link.miss = near_decq;
	    this_data->link.slip = NULL;

	    record the nodelink_data with the this_data->node.pset point set,
	    set status to operation success

	    if (status) {
		dispose of the pointer set, dispose of the actual queue object,
		free memory for data
	    } else {
		*copy = (void *) this_data;
	    }
	}
    }

    return status;
}

The reference removing routine:

int
free_decq(void *context, void *subtext, void *data,
	  const struct x1f4_nodelink_type *nodelink_data)
{
    int status;
    struct this_type *this_data;
    unsigned call;

    this_data = data;

    call = this_data->call;

    /*
     * reference count is non zero, except for some in progress object disposal
     */
    if (call) {
	call--;
	if (call) {
	    remove nodelink_data from the pset pointer set, should allow
	    operation even for non existent nodelink_data in the pointer set

	    this_data->call = call;

	    /*
	     * reference count not zero, need to check for cycles
	     */
	    status = mind_decq(context, subtext, data);
	} else {
	    status = side_decq(context, subtext, data);
	}
    } else {
	status = 0;
    }

    return status;
}

The routine transfering some reference hold by some object to some other object:

int
move_decq(void *context, void *subtext, void *data,
	  const struct x1f4_nodelink_type *nodelink_miss,
	  const struct x1f4_nodelink_type *nodelink_push)
{
    int status;

    replace the nodelink_miss in the ((struct this_type *) data)->node.pset
    point set with nodelink_push, set status to operation success

    if (status) {
    } else {
	/*
	 * some reference was removed,
	 * reference count not zero, need to check for cycles
	 */
	status = mind_decq(context, subtext, data);
    }

    return status;
}

The reference registering routine:

int
node_decq(void *context, void *subtext, void **copy, void *data,
	  const struct x1f4_nodelink_type *nodelink_data)
{
    int status;
    struct this_type *this_data;

    this_data = data;

    record the nodelink_data with the this_data->node.pset point set, set
    status to operation success

    if (status) {
    } else {
	*copy = data;

	this_data->call++;
    }

    return status;
}

The routine constructing some new queue object and setting it referred by some object (much the same as the routine constructing some new queue object and setting it referred by some variable):

int
post_decq(void *context, void *subtext, void **address,
	  const struct x1f4_nodelink_type *nodelink_data)
{
    int status;
    struct this_type *this_data;

    allocate memory for data, setup the actual queue object, set status to
    operation success

    if (status) {
    } else {
	this_data->node.call = 1;

	setup the this_data->node.pset pointer set, set status to operation
	success

	if (status) {
	    dispose of the actual queue object, free memory for data
	} else {
	    this_data->link.miss = near_decq;
	    this_data->link.slip = NULL;

	    record the nodelink_data with the this_data->node.pset point set,
	    set status to operation success

	    if (status) {
		dispose of the pointer set, dispose of the actual queue object,
		free memory for data
	    } else {
		*address = (void *) this_data;
	    }
	}
    }

    return status;
}

The routine transfering some reference hold by some object to some variable:

int
push_decq(void *context, void *subtext, void **copy, void *data,
	  const struct x1f4_nodelink_type *nodelink_data)
{
    int status;

    remove the nodelink_data from the ((struct this_type *) data)->node.pset
    point set, set status to operation success

    if (status) {
    } else {
	status = side_decq(context, subtext, *copy);
	if (status) {
	} else {
	    *copy = data;
	}
    }

    return status;
}