aerospike / aerospike-client-c

Aerospike C Client
Other
98 stars 103 forks source link

When to free udata? #92

Closed ufosky closed 4 years ago

ufosky commented 4 years ago

I have read many async function have void *udata parameter for pass context info, and some function have more than one callback (or listener) function pointer with the same udata, so when to free the udata, is there any guide? For example: The function aerospike_key_operate_async has as_async_record_listener listener and as_pipe_listener pipe_listener parameters, do I need free udata in listener or pipe_listener. Does listener or pipe_listener will be called more than once, if true, when do I need free the udata?

https://github.com/aerospike/aerospike-client-c/blob/master/src/include/aerospike/aerospike_key.h#L529

BrianNichols commented 4 years ago

udata is completely controlled by the user. The client does not allocate, free nor copy udata. The client just passes back the udata pointer to the listener.

If the user allocates udata on the heap per every async call, then it should be freed by the user in the listener callback. If udata is shared among multiple async calls, then some sort of reference counting may be necessary. If udata is global, then it does not need to be freed in the listener. If udata is NULL, then it does not need to be freed.

The listener and pipe_listener udata variables are treated separately. If the listener is called more than once (like in aerospike_scan_async), then udata should only be destroyed (using above rules) on the last call (when as_record instance is NULL in aerospike_scan_async listener).

ufosky commented 4 years ago

The function aerospike_query_async has a callback described as:

 * @param listener      The function to be called for each returned value.

if no value return, does this will be called?

ufosky commented 4 years ago

I read the example for async get like this :

    if (aerospike_key_put_async(&as, &err, NULL, &g_key, &rec, write_listener, NULL, event_loop, NULL) != AEROSPIKE_OK) {
        write_listener(&err, NULL, event_loop);
    }

If an async function returns status other than AEROSPIKE_OK, is the callback always not be called? Does I need call the callback manually for free the udata Or just free the udata on return?

BrianNichols commented 4 years ago

if no value return, does this will be called?

Yes, the listener will be called with a NULL as_record instance.

_If an async function returns status other than AEROSPIKEOK, is the callback always not be called?

Correct.

Does I need call the callback manually for free the udata Or just free the udata on return?

No, you do not need to call the listener manually. That particular example chose to call the listener on error, but this is not required. Directly freeing the udata on initial async command error will work fine.