[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [ghudson@MIT.EDU: Re: svn commit: rev 3110 - trunk/subversion/include]

From: Gerald Richter <richter_at_ecos.de>
Date: 2002-09-04 06:26:33 CEST

>
> Actually, I think it can be summarized pretty simply:
>
> * FOO returns you an object OBJ, expecting you to pass it back to its
> functions at various (later) points in time
>

The problem arises when this functions in turn call a callback where you
need the OBJ

>
> I believe both directions are solved without the embedded context pointer,
> so I'm going to go ahead and back it out. For the first case, you wrap
each
> "object" in another object:
>
> typedef struct {
> some_ptr my_data;
> int something_else;
>
> dav_resource *actual_resource;
>
> } my_dav_resource;
>
> ...
> my_dav_resource *rsrc;
>
> rsrc = apr_palloc(r->pool, sizeof(*rsrc));
> rsrc->actual_resoure = hooks->get_resource(...);
> rsrc->my_data = perl_object_wrapper(...);
>
> return rsrc;
> ...
>

This rsrc pointer works pretty well as long as there are no callbacks.
Actualy if mod_dav would not consits of so much callbacks, I never have
started this discussion. You cannot pass rsrc to any function that excepts a
dev_resource struct. If you have such a function and this function calls a
callback which gets the pointer to the dav_resource struct, you don't have a
chance inside the callback to access your custom struct. If you are the
creatator of the struct you can do what Greg suggest here:

>
> For the second case, you use embedded structures:
>
> typedef struct {
> dav_resource actual_resource;
>
> some_ptr my_data;
> int something_else;
> } my_dav_resource;
>
> ...
> my_dav_resource *rsrc;
>
> rsrc = apr_palloc(r->pool, sizeof(*rsrc));
> ...
> return &rsrc->actual_resource;
> ...
>
> void takes_a_resource(const dav_resource *r)
> {
> my_dav_resource *rsrc = (my_dav_resource *)r;
> ...

So if you pass this my_dav_resource to any function that takes a
dav_resource it works pretty well and in your callback you can access the
members at the end of the struct which contains my data. One point that
makes trouble here, is the case where you might get dav_resource or
my_dav_resource structs. How do you know which one you get? There is no
chance to get this information. (You would need to catch SIGSEGV which might
occurs somewhere later, because you accidently accessing the wrong struct
;-).

From my experiences with mod_dav 1 (and mod_dav 2 is very similiar) I think
I will catch about 80-90% with these wrappers, but to catch the remaining
10-20% it will take 80-90% of the works to get it savely done. Especialy
when threads come into play and you can't use globals to store anything
anymore. Then you need a lot of hash lookups, which make things complicated
and slow.

Here is an example to make it (hopefully) more clear:

typedef struct {
  some_ptr my_data;
  int something_else;

  dav_resource *actual_resource;

} my_dav_resource;

  ...
  my_dav_resource *rsrc;

  rsrc = apr_palloc(r->pool, sizeof(*rsrc));
  rsrc->actual_resoure = hooks->get_resource(...);
  rsrc->my_data = perl_object_wrapper(...);

// now we have to call

anotherhook -> get_parent_resource(rsrc->actual_resoure) ;

get_parent_resource might at some point call back into Perl and now I would
like to have the rsrc->my_data, but how do I get it?

That would only work if I do a

typedef struct {
  dav_resource actual_resource;

  some_ptr my_data;
  int something_else;
} my_dav_resource;

  ...
  my_dav_resource *rsrc;

  rsrc = apr_palloc(r->pool, sizeof(*rsrc));
  r = hooks->get_resource(...);
  memcpy (&rsrc->actual_resource, r, sizeof (rsrc->actual_resource)) ;
...

This way it would work, but coping such a structure around can have a lot of
unwanted side effects (for example if they are link in a list, like mod_davs
XML structs)

It seems that nobody likes the idea of a ctx pointer inside these structs. I
still find it very usefull and it would save a lot of work for people who
like to interface to these structs, but I do not insist on these (and cannot
do because I neither a programmer of mod_dav nor of subversion, but I like
both :-).

Gerald

-------------------------------------------------------------
Gerald Richter ecos electronic communication services gmbh
Internetconnect * Webserver/-design/-datenbanken * Consulting

Post: Tulpenstrasse 5 D-55276 Dienheim b. Mainz
E-Mail: richter@ecos.de Voice: +49 6133 925131
WWW: http://www.ecos.de Fax: +49 6133 925152
-------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Sep 4 06:22:03 2002

This is an archived mail posted to the Subversion Dev mailing list.