Hi
In looking to improve the usability of libqb functions (mainly ipc client & server
functions).
I started looking at the way glib & dbus do it.
GMainLoop * g_main_loop_new (GMainContext *context,
gboolean is_running);
GMainContext * g_main_context_new (void);
GSource * g_timeout_source_new (guint interval);
glib describes these returned types as "opaque". You can't do anything to
them directly.
DBusConnection * dbus_connection_open (const char *address, DBusError *error);
dbus says: "All fields are private."
So the returned type has no real value to the user - it is just a pointer you have to
use.
Both glib and dbus provide reference and dereference functions to prevent these pointers
from been freed by other code (in another thread). They use atomic inc & dec
functions.
The current API of corosync is "inherited" from the AIS API.
This looks like:
a_handle_t handle;
res = something_create (args ..., &handle);
...
res = something_get (handle, ...);
...
something_destroy (handle);
Here handles are like file handles to represent an object. Every time you
open/create an "object", it has a reference count incremented.
So both take care of reference counting but if you have an old pointer/handle
to a destroyed object then the pointer method would result in a crash if you
dereferenced it where as the handle method would result in a "bad handle"
error code.
Which is better?.
1)
The pointer API seems to be a little more friendly/obvious to me.
Also it is typed in that you will get a compiler error if you pass GSource*
into a function expecting a GMainLoop* argument (although this could be done with handles
too).
2)
The handle seems a little safer if you have old/stale references.
3)
It is also good to be "like the others" in terms of familiarity to developers
(easy of use).
Are there any other arguments for either type of API?
Another question is the way return codes are returned:
1)
APointer* obj;
SomeStatus ret;
obj = xyz_create("something", &ret);
if (!obj) {
xyz_print_error(ret);
return;
}
2)
a_handle_t handle;
int ret;
ret = xyz_create ("something", &handle);
if (ret != 0) {
perror (ret);
return;
}
Any opinions on these?
Basically the question is:
Do we follow posix API or libraries like glib/libevent/dbus?
I am leaning towards the "glib/libevent/dbus" style API as libqb
is at a similar layer. We are providing higher layer functionality
on top of a posix API.
-Angus