> Patrik Stridvall <psÉleissner.se> writes:
>
> > As for in how many places function pointers are used in
> non-trival ways
> > that remains to be investigated. WNDPROC, HOOKPROC,
> TIMERPROC, ABORTPROC
> > and KEYB_EVENT_PROC are the are the only ones I have found currently
> > supported in Win16. There might be more in Win32 though,
> but I haven't
> > found any yet. There will be a few lines new code for each place.
>
> Don't forget that Winelib apps may be using function pointers too; and
> having to change the app source is not an option.
Well, as long as you only call WineLib and don't try to call
emulated DLL:s _directly_ everything will work fine.
If neither the application nor the emulated DLL tells the thunking layer
about need and the lifetime of the thunks there is no way it can know
when to allocate or deallocate a thunk. So in theory the problem is
unsolvable due to lack of information.
Fortunately, from a practical point of view it is possible, at least in
some cases, to have custom made thunking layer for each DLL. This
involves a human to provide the missing information.
This is what the Win16 thunking layer does for the trivial Enum* functions.
The non-trivial cases like WINPROC, HOOKPROC etc are not handled this way,
they are handled by changing the WineLib implementation.
There is no fundamental different between the problems faced by WineLib
and the problems faced by the application so seen from that perspective
the application. So if you forbid changing the application you can
as well forbid changing WineLib because they are bascily the same problem.
So can we solve this problem? In theory no, the thunking layer
can't even with the help a human handle all possible _theoretical_
case, since while the communication betwen the different sides
is known, the state of either side is not availible. So in theory
the moment when the lifetime of a thunk has expired can never be
known in all cases, not even with human help.
However, in pratices there is one possibillity that I don't like,
since it can't handle all teoretical cases. It might be acceptle
in practice though.
Very simply, we assume that the lifetime of each thunk is infinite
and allow sharing of thunks. As long as the communication (function calls)
through the thunking layer is documented, it is always possible for a
human to understand what is a function pointer and what is not.
For each function pointer simple allocate a thunk with infinate
lifetime if it doesn't already has been allocated in that case we share
it. This will leak memory, however in _normal_ application the number
of functions used as function pointers is limited, so this is not
a problem since because of sharing only one thunk per possible
value of a function pointer will exist.
The drawback is that if you applications in a language that allows
dynamic generation of functions, the memory used by the thunks
is unbounded. This is perhaps mostly a theoretical problem,
but I don't like it.
> You are welcome to submit a patch, but I doubt that you will be able
> to make it non-intrusive enough to be acceptable. Feel free to prove
> me wrong...
You will have to choose between a
(1) Theoretically unsound, but in most realistic cases usable solution,
that doesn't require application and standard WineLib file changes
(2) Theoretically sound, and in all cases usable solution,
that requires application and standard WineLib file changes
The Win16 thunking currently uses (2), but we have no application support
for Win16 so it matters less there.
If you think (1) is an potentially acceptable solution I can make the
Win16 thunking layer use it as a proof of concept. It will not take that
much time to do that I think, then we will see if my ideas will work I
am not 100% sure yet.