[Dar-libdar_api] Re context variable in callbacks
For full, incremental, compressed and encrypted backups or archives
Brought to you by:
edrusb
|
From: Johnathan B. <jk...@us...> - 2004-06-17 03:34:21
|
Hi Denis,
Unfortunately, I only just read your reply to my post! I never got the=20
reply from sourceforge, even though I was confirmed as a member of the=20
dar_api mailing list...I only got a message that my post was waiting to be=
=20
reviewed by the moderator. Too bad, as I would have liked to have=20
discussed this further with you before you went ahead with coding.
> Apparently it is standard coding practice for API callback functions to
> accept a "context value", which is a void *, that allows one to use a
> class member function as a callback without resorting to a global=20
> pointer
> variable.
=20
> Well, to my point of view, after having read the tutorial you give
> reference bellow, there is no standard coding practice that speaks about
> a "context value" for callback. The "context value" is used as a trick
> to make a callback function pointing to non-static member functions of a
> C++ class. The trick implies a static method or normal function to=20
> explicitely pass the "this" pointer (pointer to the current object which=
=20
> is a hidden argument in C++) as explicit argument.
=20
I based that statement on something a professional programmer told me --- I=
=20
can only take him at his word. In fact I was not able to find anything in=20
any reference books on C++ programming that explains context variables for=
=20
callback functions. The tutorial is the closest thing I could come up=20
with.
> Now my question, is do we need libdar calling a non-static member of a
> given object (as callback) ?
As I understand static member functions, you are not allowed to change=20
their member variables. So in order to return a boolean from the callback,=
=20
we need non-static member functions whose variables can be altered. Right?
>First there is a risk, if this objects dies, we will have big problems
>like memory violations. But OK, if you give a wrong argument as address=20
>of the callback function we get to the same point.
=20
> Second, libdar would always call the method of the same object, and it
> would require first, a way for kdar (for example) to tell libdar which
> object address (the "this" argument) to give to the callback function in
> the "context value".
> Third, logically, it is a class defined in the user application like
>kdar, and libdar does not know anything about this class. This would not
>be very useful to libdar point of view.
=20
I don't understand. Libdar does not understand anything about the regular=20
callback function either, which is the point of having the callback=20
function.
>
> As I understand dar, it uses a regular function as the callback.=20
> Could you
> add perhaps a new set of callback setting functions to the libdar API=20
>that
> accept a void * context value to be passed. It would be easy to keep
> backwards compatibility with earlier libdar versions by redefining the
> standard callback setting functions to call the new ones with NULL=20
>for the
> void *.
=20
>Yes, this is still possible.
=20
> I think the need behind is the thread safe libdar library. If the
> library is thread safe, there must not be a function in the API that
> receive the address of a callback function without any context.
=20
> Let"s take an example:
=20
> actually (version 2.1.2 is the last release) libdar API proposes the
> following function:
=20
> set_warning_callback(&my_warning_callback);
=20
>to reach thread safe level, set_warning_callback must have a contextual=20
>argument, to have a thread discriminant, the callback function stays the=
=20
>same. In my idea actually, a possible solution is a new class that will=20
>gather all static variables that currently make the libdar thread=20
>unsafe. I have not yet a name for that class, so let"s call it "junk"=20
>for now. We would then have set_warning_callback a method of the "junk"=20
>class, and probably any other functions of the current API (op_create,=20
>etc.)
=20
>Before anything else, each thread should create its own "junk" object=20
>forcing the calling application to give a thread specific callback=20
>function in the "junk" constructor.
=20
>OK now, I see, if you have several threads, you could give several=20
>callback functions (one per thread), but that could lead to some=20
>ineficiency, you could rather give the same callback function to all=20
>thread and have an additional argument in the callback prototype that=20
>tell this common callback function which thread it is called from, and=20
>which action to do (which object to call, etc...). A void pointer should=
=20
>be effectively interesting as it could carry the address to a function=20
>or the address to an object which method to call.
>=20
>we would have someting like this:
=20
I'm lost on all of this. I don't know anything yet about making libraries=20
thread-safe. Is the issue that two instances of a libdar operation,
say isolation and diffing, might try to call the same callback function at=
=20
the same time?
> class junk
>{
>public:
> set_warning_callback(void (*callback)(const std::string &x,
> void *context) )
> { warning_callback =3D callback; };
>set_warning_callback_context_to_give(void *context)
> { context_to_give =3D context; };
>
> op_create(....);
> op_create_noexcept(...);
> [...]
=20
> private:
> void *context_to_give;
> void (*warning_callback)(const std::string &x, void *context);
>};
=20
>and inside a give thread :
=20
> ...
> junk toto;
> toto.set_warning_callback(&mycallback);
> toto.set_warning_context_to_give(this);
> toto.op_create_noexcept(...);
> ...
=20
>with the global callback function:
=20
> void mycallback(const std::string &x, void *context)
> {
> context->some_method(x);
> // well, this is much simplified.
>}
=20
=20
> Does this makes sens to you ?
=20
Not yet. I have to put some serious thought into all of this. Feels a lot=20
like you're reinventing the wheel. Unfortunately I'm not much help, and=20
neither do the texts that I've looked at. Do you know any good books on=20
C++ library programming that you could point me to?
>
> There is a good tutorial at
> http://www.function-pointer.org/callback.html
> #3: How to Implement Callbacks in C and C++
>
> In the examples given, I currently use method B, but it would be=20
>better to
> use method A to avoid using the global variable.
=20
>I agree, I dislike global variables.
Glad to see that libdar is on track to be thread-safe.
I updated the cvs, but the docs need some work, so I'll put off the API3=20
upgrade to KDar until later.
Best regards,
JB
=20
=2D-=20
Johnathan K. Burchill, Ph.D.
jk...@us...
|