Re: Re context variable in callbacks
Denis Corbin <[email protected]> Thu, 17 Jun 2004 20:45:05 +0200
| Newsgroups | gmane.comp.sysutils.backup.dar.libdar |
|---|---|
| Organization | none |
| Message-ID | <[email protected]> |
Johnathan Burchill wrote:
> Hi Denis,
Hello Johnathan,
>
> Unfortunately, I only just read your reply to my post! I never got the
> reply from sourceforge, even though I was confirmed as a member of the
> dar_api mailing list...I only got a message that my post was waiting to be
> reviewed by the moderator. Too bad, as I would have liked to have
> discussed this further with you before you went ahead with coding.
strange, there is still one of your email address in the list... Well
the coding done is a lot code cleaning to have a thread safe library.
Few conceptions changes were necessary to reach this aim like the
"user_interaction" class but I don't think you've missed the most
interesting part ;)
>
> > 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
> > pointer
> > variable.
>
>
>>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
>>explicitely pass the "this" pointer (pointer to the current object which
>>is a hidden argument in C++) as explicit argument.
>
>
> I based that statement on something a professional programmer told me --- I
> can only take him at his word. In fact I was not able to find anything in
> any reference books on C++ programming that explains context variables for
> callback functions. The tutorial is the closest thing I could come up
> with.
Whatever standard programming it is or not, It makes a lot of sens. So
as I said I will go this way.
>
>
>>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
> their member variables. So in order to return a boolean from the callback,
> we need non-static member functions whose variables can be altered. Right?
you are right about static member functions, they are not part of any
object but global to a class, so they cannot access to the data of a
particular object (non static data member).
>[...]
>
> >kdar, and libdar does not know anything about this class. This would not
> >be very useful to libdar point of view.
>
> I don't understand. Libdar does not understand anything about the regular
> callback function either, which is the point of having the callback
> function.
I think I make a mistake and wanted to say "dar and libdar" do not (have
to) know kdar own data structure.
>
> >
> > As I understand dar, it uses a regular function as the callback.
>
>>Could you
>
> > add perhaps a new set of callback setting functions to the libdar API
> >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
> >for the
> > void *.
>
> >Yes, this is still possible.
>
>
>>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.
>
>
>
>>Let"s take an example:
>
>
>
>>actually (version 2.1.2 is the last release) libdar API proposes the
>>following function:
>
>
>
>> set_warning_callback(&my_warning_callback);
>
>
> >to reach thread safe level, set_warning_callback must have a contextual
> >argument, to have a thread discriminant, the callback function stays the
> >same. In my idea actually, a possible solution is a new class that will
> >gather all static variables that currently make the libdar thread
> >unsafe. I have not yet a name for that class, so let"s call it "junk"
> >for now. We would then have set_warning_callback a method of the "junk"
> >class, and probably any other functions of the current API (op_create,
>
>>etc.)
>
>
> >Before anything else, each thread should create its own "junk" object
> >forcing the calling application to give a thread specific callback
> >function in the "junk" constructor.
>
> >OK now, I see, if you have several threads, you could give several
> >callback functions (one per thread), but that could lead to some
> >ineficiency, you could rather give the same callback function to all
> >thread and have an additional argument in the callback prototype that
> >tell this common callback function which thread it is called from, and
> >which action to do (which object to call, etc...). A void pointer should
> >be effectively interesting as it could carry the address to a function
> >or the address to an object which method to call.
>
> >we would have someting like this:
>
> I'm lost on all of this. I don't know anything yet about making libraries
> 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
> the same time?
Well, the work about thread-safe libdar is the following: Several API
functions on variable not passed as argument (the callback functions for
example), and some value passed in argument were stored as class static
data (like compression algorithm used, and several other things). So
theses variables are shared by all the running threads, causing a
problem if you want modify theses variables.
Now, all parameters needed for API functions are passed as argument and
stay on the stack (they are passed as argument and temporary variables
stay "local" to functions). One exception concerns the special
allocation scheme, which must stay global (the ::new and ::delete
operator cannot be else), this scheme needs global variable and any
change to theses variable is now in a critical section thanks to a mutex
(Posix threading). This allow several threads to run without the risk of
having one destructing the variable set by another one.
But as I said, theses changes are mainly internal to the libdar library.
>
>
>>class junk
>
> >{
> >public:
> > set_warning_callback(void (*callback)(const std::string &x,
> > void *context) )
> > { warning_callback = callback; };
> >set_warning_callback_context_to_give(void *context)
> > { context_to_give = context; };
> >
> > op_create(....);
> > op_create_noexcept(...);
> > [...]
>
>
>>private:
>
> > void *context_to_give;
> > void (*warning_callback)(const std::string &x, void *context);
> >};
>
> >and inside a give thread :
>
> > ...
> > junk toto;
> > toto.set_warning_callback(&mycallback);
> > toto.set_warning_context_to_give(this);
> > toto.op_create_noexcept(...);
> > ...
>
> >with the global callback function:
>
> > void mycallback(const std::string &x, void *context)
> > {
> > context->some_method(x);
> > // well, this is much simplified.
> >}
>
>
>
>>Does this makes sens to you ?
>
>
> Not yet. I have to put some serious thought into all of this. Feels a lot
> like you're reinventing the wheel. Unfortunately I'm not much help, and
> neither do the texts that I've looked at. Do you know any good books on
> C++ library programming that you could point me to?
first you can forget the junk class, it was not necessary to introduce
it in the API. Second I suggest having a look at user_interaction.hpp
and lidar.hpp as well as the raw notes in doc/DOC_API3 (taken from CVS)
to have a idea of the changes brought to the API.
I don't think I am reiventing the wheel (at least now) :-). I had some
good books about C++ programming and C library at the time I was student
in computer science,... but today I build dar based on my souvenirs
;-) and my programming experience. I don't pretend doing totally
academic things.
>
> >
> > 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
> >better to
> > use method A to avoid using the global variable.
>
> >I agree, I dislike global variables.
>
> Glad to see that libdar is on track to be thread-safe.
it should be thread-safe now.
> I updated the cvs, but the docs need some work, so I'll put off the API3
sure they need ! In fact, API3 is for me today a reminder of changes
done, as there will be probably some others before 2.2.0. I also plan to
have all documentation in HTML, which is portable format, and allow
better readability than pure text. :-)
> upgrade to KDar until later.
I will contact you through this mailing-list when the API will be frozen
for release 2.2.0 (at that time new features will be for following
release). Tjis will take place a few weeks before pre-release time, so
we can integrate you needs in the API if necessary.
>
> Best regards,
> JB
>
Kind Regards,
Denis.
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND