I am planning to extend the dispatch table
and was thinking about the consequences for
user defined formats (UDF).
The problem is that the dispatch table format
provided by the user's client code could potentially be different
than that being used by libnetcdf. This means that the # of entries
in the users' table could be more or less (or equal) to the #
of entries in the libnetcdf dispatch table and there is no way
to determine the relative sizes and therefore the relative
compatibility.
I am not sure if this is a problem in practice.
Consider the cases, and assume that the client code is compiled.
- |client table| < |libnetcdf table| -- presumably the client code
will not (indirectly or directly) invoke any entries that are
not in its table. So that should work ok. However if, for some reason,
the libnetcdf code internally invokes the extra entries, this will
lead to a memory fault trying to access past the end of the user's table.
- |client table| > |libnetcdf table| -- presumably this will fail
at compile time because the client code will reference functions
not known to libnetcdf, so this should be ok. The only potential
problem is with cross dispatch table calls where the UDF code
attempts to call the new entries, but for some dispatch table
other than the UDF table.
Notes:
- In case 1, if this bumps the .so number, it should be ok,
but I do not know if we currently take this into account when
defining the .so number.
- The other case where we can get into trouble is with interpretive
systems such as python where we can, in principle, synthesize
a call to one of the new entries. In this case we could see various
memory or segfault errors.
- I am implementing the ability to define multiple filters per variable.
One implementation I am considering is the re-implementation of
the first level filter functions (e.g. nc_def_var_filter)
to invoke a new function called filter_actions.
This would fail for case 1 because the nc_def_var_filter wrapper code
in libdispatch/dvar.c would attempt to access the filter_actions
entry in the UDF and that would fail.
There are some implications here. In effect, by exporting the dispatch
table format we are not only limiting changes to it, but we must also
limit the implementations of the wrapper functions (like nc_def_var_filter)
so that they always invoke the same dispatch table entries; they cannot
be changed to use new function in the dispatch table.
Adding a version number to the actual dispatch table would
allow graceful failure for some of the above cases, but not all of them.
Bottom line: UDF needs more thought before we release it into the wild.
I am planning to extend the dispatch table
and was thinking about the consequences for
user defined formats (UDF).
The problem is that the dispatch table format
provided by the user's client code could potentially be different
than that being used by libnetcdf. This means that the # of entries
in the users' table could be more or less (or equal) to the #
of entries in the libnetcdf dispatch table and there is no way
to determine the relative sizes and therefore the relative
compatibility.
I am not sure if this is a problem in practice.
Consider the cases, and assume that the client code is compiled.
will not (indirectly or directly) invoke any entries that are
not in its table. So that should work ok. However if, for some reason,
the libnetcdf code internally invokes the extra entries, this will
lead to a memory fault trying to access past the end of the user's table.
at compile time because the client code will reference functions
not known to libnetcdf, so this should be ok. The only potential
problem is with cross dispatch table calls where the UDF code
attempts to call the new entries, but for some dispatch table
other than the UDF table.
Notes:
but I do not know if we currently take this into account when
defining the .so number.
systems such as python where we can, in principle, synthesize
a call to one of the new entries. In this case we could see various
memory or segfault errors.
One implementation I am considering is the re-implementation of
the first level filter functions (e.g. nc_def_var_filter)
to invoke a new function called filter_actions.
This would fail for case 1 because the nc_def_var_filter wrapper code
in libdispatch/dvar.c would attempt to access the filter_actions
entry in the UDF and that would fail.
There are some implications here. In effect, by exporting the dispatch
table format we are not only limiting changes to it, but we must also
limit the implementations of the wrapper functions (like nc_def_var_filter)
so that they always invoke the same dispatch table entries; they cannot
be changed to use new function in the dispatch table.
Adding a version number to the actual dispatch table would
allow graceful failure for some of the above cases, but not all of them.
Bottom line: UDF needs more thought before we release it into the wild.